面试(05)————Redis篇

目录

一、项目中哪些地方使用了redis

 问题一:发生了缓存穿透该怎么解决?

方案一:缓存空数据

方案二:布隆过滤器

模拟面试

问题二: 发生了缓存击穿该怎么解决?

 方案一:互斥锁

 方案二:逻辑过期 

 模拟面试

问题三: 发生了缓存雪崩该怎么解决?

问题四: redis作为缓存,mysql的数据如何redis进行同步?(双写一致性)

 这个时候我们就要考虑是先删除缓存,还是先修改数据库?

情况一:先删除缓存,再操作数据库

情况二:先操作数据库,再删除缓存

那么为什么要删除两次缓存? 

为什么要延时删除?

业务场景一:那怎么保证双写一致呐?(一致性要求高的业务需求)

 业务场景二:延迟一致怎么做?(允许短暂的不一致,实际开发中最为主流的)

方案一:基于MQ的异步通知

方案二:基于Canal的异步通知

 模拟面试

 问题五:redis作为缓存,数据的持久化是怎么做的?

 RDB

AOF

RDB与AOD对比 

模拟面试

​编辑 问题六:假设redis的key过期之后,会立即删除吗?(数据过期策略)

惰性删除 

定期删除 

模拟面试 

问题七: 假如缓存过多,内存是有限的,内存被占满了怎么办?(数据淘汰策略)

关于数据淘汰策略其他的面试问题?

1、数据库有1000万数据,Redis只能缓存20w数据,如何保证Redis中的数据都是热点数据?

2、Redis的内存用完了会发生什么?

模拟面试

问题八:redis分布式锁,是如何实现的?

情景模拟———抢券执行

redis分布式锁

Redis实现分布式锁如何合理的控制锁的有效时长?

redisson实现的分布式锁——执行流程

redisoon实现的分布式锁,是否可以重入呐?

redisson实现的分布式锁——主从一致性

模拟面试

问题九:redis集群有哪些方案?

 主从复制

主从全量同步

主从增量同步 (slave重启或后期数据变化)

模拟面试

 哨兵的作用

结构

作用

服务状态监控

Redis集群(哨兵模式)脑裂

模拟面试

分片集群结构

数据读写 

模拟面试

 总结

 问题十:Redis是单线程的,但是为什么还那么快?

能解释一下I/O多路复用 模型?

 用户空间和内核空间

阻塞IO

非阻塞IO

IO多路复用 

 Redis网络模型

模拟面试


以下问题包括知识点和面试题,看的时候直接看《模拟面试即可》,后续持续更新中。。。 

一、项目中哪些地方使用了redis

面试官:我看你做的项目中,都用到了redis,你在最近的项目中哪些场景使用了redis?

 一般这个问题要结合自己的实际项目经历回答,面试想这样问:一方面验证你的项目场景的真实性,二是为了作为深入发问的切入点

比如你回答了使用了:(可能会被问道的相关问题或知识点)

缓存:缓存三兄弟(穿透、击穿、雪崩)、双写一致、持久化、数据过期策略、数据淘汰策略
 

分布式锁:setnx、redisson
 

消息队列、延迟队列:何种数据类型

 问题一:发生了缓存穿透该怎么解决?

以下是正常使用缓存的流程:

那么什么是缓存穿透呐?

查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都去查询数据库

 那为什么会出现这种情况呐?

通常呐,就是有人恶意攻击你的系统,有人知道你的请求路径,知道你的请求参数跟在请求路径后面的,就会制造一些假的id发起请求等等,就会冲击你的数据库,你的数据库的并发是不高的,请求到了一定的量就会击垮数据库。

 解决方案:

方案一:缓存空数据

解决方案一:缓存空数据,查询返回的数据为空,仍把这个空数据进行缓存

优点:操作简单

缺点:消耗内存,可能会发生不一致的问题

方案二:布隆过滤器

 解决方案二:布隆过滤器

优点:内存占用较少,没有多余key

缺点:实现复杂,存在误判

布隆过滤器:


bitmap(位图):相当于一个以(bit)位为单位的数组,数组中每个单元只能存储二进制数0或1

布隆过滤器作用:布隆过滤器可以用于检索一个元素是否再一个集合中。

可能产生误判:

误判率:数组越小误判率就越大,数组越大误判率就越小,但是同时带来了更多的内存消耗

模拟面试

问题二: 发生了缓存击穿该怎么解决?

什么是缓存击穿?

给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把数据库压垮

 解决方案:

 方案一:互斥锁

特点:强一致,性能差

 方案二:逻辑过期 

特点:高可用、性能优、不能保证数据的绝对一致

 模拟面试

问题三: 发生了缓存雪崩该怎么解决?

什么是缓存雪崩?

在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力

解决方案:

  • 给不同的key的TTL添加随机值
  • 利用Redis集群提高服务的可用性
  • 给缓存业务添加降级限流策略  (降级可作为系统的保底策略,适用于穿透、击穿、雪崩)
  • 给业务添加多级缓存

 模拟面试:

问题四: redis作为缓存,mysql的数据如何redis进行同步?(双写一致性)

一定要设置前提,,,结合自己的项目业务背景去讲!!!!

看看到底属于哪一种:是一致性要求高的业务需求,还是说是允许延迟一致?

双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致

读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,设定超时时间

写操作:延迟双删 

 这个时候我们就要考虑是先删除缓存,还是先修改数据库?

情况一:先删除缓存,再操作数据库

正常情况:

不正常情况:因为线程是交替执行的,这种方式可能会出现脏数据的现象

情况二:先操作数据库,再删除缓存

正常情况:

不正常情况:这种方式可能会出现脏数据的现象

那么为什么要删除两次缓存? 

降低脏数据的出现

为什么要延时删除?

业务场景一:那怎么保证双写一致呐?(一致性要求高的业务需求)

但是这样的话,性能就有点差了

当然我们都是知道的,放入redis的数据一般都是读多写少

所以使用读写锁就可以了

特点:强一致,性能差(强一致性情况下才会使用)

共享锁:读锁readLock,加锁之后,其他线程可以共享读操作

排他锁:独占锁writeLock,加锁之后,阻塞其他线程读写操作

 业务场景二:延迟一致怎么做?(允许短暂的不一致,实际开发中最为主流的)

方案一:基于MQ的异步通知

方案二:基于Canal的异步通知

 模拟面试

强一致性回答:

最终一致性回答:

 问题五:redis作为缓存,数据的持久化是怎么做的?

 RDB

什么是RDB呐?

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中所有数据记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,回复数据

人工主动备份:

Redis自动备份:

Redis内部有触发RDB的机制,可以再redis.conf文件中找到,格式如下:

 RDB的执行原理:

bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入RDB文件。

fork采用的是copy-write技术:

  • 当主进程执行读操作时,访问共享内存;
  • 当主进程执行写操作时,则会拷贝一份数据,执行写操作。

优点 :

1. 整个Redis数据库将只包含⼀个⽂件 dump.rdb,⽅便持久化。
2. 容灾性好,⽅便备份。
3. 性能最⼤化,fork ⼦进程来完成写操作,让主进程继续处理命令,所以是 IO 最⼤化。使⽤单独⼦
进程来进⾏持久化,主进程不会进⾏任何 IO 操作,保证了 redis 的⾼性能
4. 相对于数据集⼤时,⽐ AOF 的启动效率更⾼。
 
缺点:
1. 数据安全性低。RDB 是间隔⼀段时间进⾏持久化,如果持久化之间 redis 发⽣故障,会发⽣数据丢
失。所以这种⽅式更适合数据要求不严谨的时候)
2. 由于RDB是通过fork⼦进程来协助完成数据持久化⼯作的,因此,如果当数据集较⼤时,可能会导
致整个服务器停⽌服务⼏百毫秒,甚⾄是1秒钟

AOF

什么是AOF呐?

AOF全称Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看作是命令日志文件。


优点:

1. 数据安全,Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也
是异步完成的,其效率也是⾮常⾼的,所差的是⼀旦系统出现宕机现象,那么这⼀秒钟之内修改的
数据将会丢失。⽽每修改同步,我们可以将其视为同步持久化,即每次发⽣的数据变化都会被⽴即
记录到磁盘中。。
2. 通过 append 模式写⽂件,即使中途服务器宕机也不会破坏已经存在的内容,可以通过 redis
check-aof ⼯具解决数据⼀致性问题。
3. AOF 机制的 rewrite 模式。定期对AOF⽂件进⾏重写,以达到压缩的⽬的

缺点:

1、 因为是记录命令,AOF文件会比RDB文件大得多。而且AOF会记录对同一个key的多次写操作,单只有最后一次写操作才有意义。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同的效果。

2、 数据集⼤的时候,⽐ rdb 启动效率低。
3、运⾏效率没有RDB⾼

 Redis也会在触发阈值时自动去重写AOF文件。阈值也可以在redis.conf中配置:

RDB与AOD对比 

模拟面试

 问题六:假设redis的key过期之后,会立即删除吗?(数据过期策略)

什么是数据过期策略呐?

Redis对数据设置数据的有效时间,数据过期以后,就需要将数据从内存中删除掉。可以按照不同的规则进行删除,这种删除规则就被称之为数据的删除策略(数据过期策略)

惰性删除 

惰性删除:设置该key过期时间后,我们不去管它,当需要该key时,我们再检查其是否过期,如果过期,我们就删掉它,反之返回该key

 优点:对CPU友好,只会在使用该key时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查

缺点:堆内存不好,如果一个key已经过期,但是一直没有使用,那么该key就会一直存在内存中,内存永远不会释放

定期删除 

什么是定期删除呐?

每隔一段时间,我们就对一些key进行检查,删除里面过期的key(从一定数量的数据库中取出一定数量的随机key进行检查,并删除其中的过期key)。

定期清理的两种模式

  • SLOW模式 是定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配置文件redis.conf的hz选项来调整这个次数
  • FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms

优点: 可以通过限制删除操作执行的时长和频率来减少删除操作对CPU的影响。另外定期删除,也能有效释放过期键占用的内存。


缺点:难以确定删除操作执行的时长和频率。

 Redis的过期删除策略:惰性删除 + 定期删除两种策略进行配合使用

模拟面试 

问题七: 假如缓存过多,内存是有限的,内存被占满了怎么办?(数据淘汰策略)

什么是数据淘汰策略?

当Redis中的内存不够用时,此时再向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。

 LRU例子:key1是在3s之前访问的,key2是在9s之前访问的,删除的就是key2

LFU例子:key1最近5s访问了4次,key2最近5s访问了9次,删除的就是key1

 

关于数据淘汰策略其他的面试问题?

1、数据库有1000万数据,Redis只能缓存20w数据,如何保证Redis中的数据都是热点数据?

2、Redis的内存用完了会发生什么?

模拟面试

以上问题都是基于你的项目:redis使用的场景是缓存这部分;下面则是基于你的项目redis使用场景是分布式锁

问题八:redis分布式锁,是如何实现的?

情景模拟———抢券执行

正常情况:

异常情况:

当线程1执行完,此时的库存是0,当线程2执行完之后,库存再减一,就变成-1了,就会出现超卖的情况

加锁操作:

适用于单体项目,服务只部署在一台服务器上的,这个方法是没问题的,但是往往我们的服务都是集群的

分布式锁解决这个问题:

redis分布式锁

Redis实现分布式锁主要利用Redis的setnx命令。setnx是SET if not exists(如果不存在,则SET)的缩写。



 

1. ⾸先利⽤setnx来保证:如果key不存在才能获取到锁,如果key存在,则获取不到锁
2. 然后还要利⽤lua脚本来保证多个redis操作的原⼦性
3. 同时还要考虑到锁过期,所以需要额外的⼀个看⻔狗定时任务来监听锁是否需要续约
4. 同时还要考虑到redis节点挂掉后的情况,所以需要采⽤红锁的⽅式来同时向N/2+1个节点申请锁,
都申请到了才证明获取锁成功,这样就算其中某个redis节点挂掉了,锁也不能被其他客户端获取到

Redis实现分布式锁如何合理的控制锁的有效时长?

根据业务执行时间预估
 

给锁续期

redisson实现的分布式锁——执行流程

实例代码:

redisoon实现的分布式锁,是否可以重入呐?

可重入,利用hash结构记录线程id和重入次数

redisson实现的分布式锁——主从一致性

RedLock(红锁):不能只在一个redis实例上创建锁,应该是在多个redis实例上创建锁(n/2+1),避免在一个redis实例上加锁。

模拟面试

下面则是redis其他的问题

问题九:redis集群有哪些方案?

主从复制

哨兵模式

分片集群

 主从复制

 单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。


 

通过执⾏slaveof命令或设置slaveof选项,让⼀个服务器去复制另⼀个服务器的数据。主数据库可以进 ⾏读写操作,当写操作导致数据变化时会⾃动将数据同步给从数据库。⽽从数据库⼀般是只读的,并接 受主数据库同步过来的数据。⼀个主数据库可以拥有多个从数据库,⽽⼀个从数据库只能拥有⼀个主数据库。

主从全量同步

1. 主节点通过bgsave命令fork⼦进程进⾏RDB持久化,该过程是⾮常消耗CPU、内存(⻚表复制)、硬
盘IO的
2. 主节点通过⽹络将RDB⽂件发送给从节点,对主从节点的带宽都会带来很⼤的消耗
3. 从节点清空⽼数据、载⼊新RDB⽂件的过程是阻塞的,⽆法响应客户端的命令;如果从节点执⾏
bgrewriteaof,也会带来额外的消耗

主从增量同步 (slave重启或后期数据变化)

1. 复制偏移量:执⾏复制的双⽅,主从节点,分别会维护⼀个复制偏移量offset
2. 复制积压缓冲区:主节点内部维护了⼀个固定⻓度的、先进先出(FIFO)队列 作为复制积压缓冲区,
当主从节点offset的差距过⼤超过缓冲区⻓度时,将⽆法执⾏部分复制,只能执⾏全量复制。
3. 服务器运⾏ID(runid):每个Redis节点,都有其运⾏ID,运⾏ID由节点在启动时⾃动⽣成,主节点会
将⾃⼰的运⾏ID发送给从节点,从节点会将主节点的运⾏ID存起来。 从节点Redis断开重连的时
候,就是根据运⾏ID来判断同步的进度:
如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会继续
尝试使⽤部分复制(到底能不能部分复制还要看offset和复制积压缓冲区的情况);
如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的Redis节点并不
是当前的主节点,只能进⾏全量复制。

模拟面试

 哨兵的作用

Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复

结构

作用

服务状态监控

Redis集群(哨兵模式)脑裂

模拟面试

分片集群结构

 

数据读写 

Redis分片集群引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽

模拟面试

 总结

Redis提供了三种集群策略:
1. 主从模式:这种模式⽐较简单,主库可以读写,并且会和从库进⾏数据同步,这种模式下,客户端 直接连主库或某个从库,但是但主库或从库宕机后,客户端需要⼿动修改IP,另外,这种模式也⽐ 较难进⾏扩容,整个集群所能存储的数据受到某台机器的内存容量,所以不可能⽀持特⼤数据量
2. 哨兵模式:这种模式在主从的基础上新增了哨兵节点,但主库节点宕机后,哨兵会发现主库节点宕 机,然后在从库中选择⼀个库作为进的主库,另外哨兵也可以做集群,从⽽可以保证但某⼀个哨兵 节点宕机后,还有其他哨兵节点可以继续⼯作,这种模式可以⽐较好的保证Redis集群的⾼可⽤,但 是仍然不能很好的解决Redis的容量上限问题。
3. Cluster模式:Cluster模式是⽤得⽐较多的模式,它⽀持多主多从,这种模式会按照key进⾏槽位的 分配,可以使得不同的key分散到不同的主节点上,利⽤这种模式可以使得整个集群⽀持更⼤的数据容量,同时每个主节点可以拥有⾃⼰的多个从节点,如果该主节点宕机,会从它的从节点中选举⼀ 个新的主节点。
对于这三种模式,如果Redis要存的数据量不⼤,可以选择哨兵模式,如果Redis要存的数据量⼤,并且 需要持续的扩容,那么选择Cluster模式。

 问题十:Redis是单线程的,但是为什么还那么快?

能解释一下I/O多路复用 模型?

 用户空间和内核空间

阻塞IO

非阻塞IO

IO多路复用 

IO多路复用:是利用单个线程来同时监听多个Socket,并在某个Socket可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。不过监听Scoket的方式、通知的方式又有多种实现,常见的有:

select

poll

epoll

 Redis网络模型

Redis通过IO多路复用来提高网络性能,并支持各种不同的多路复用实现,并且将这些实现进行封装,提供了统一的高性能事件库

模拟面试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/635978.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaWeb-登录校验

会话技术 浏览器使用的是http协议,多次请求间数据是不能共享的,例如我们要去访问用户数据的接口,但这时候用户是否已经登入了呢?是不知道的,为了解决这个问题,于是引入了会话跟踪技术。 会话:…

windows驱动开发-WDM框架(二)

DriverEntry 每个驱动程序必须具有 DriverEntry 例程,用于初始化驱动程序范围的数据结构和资源。 在支持即插即用 (PnP) 的驱动程序中,与所有驱动程序一样,DriverEntry 例程负责驱动程序初始化,而 AddDevice 例程负责设备初始化…

自然语言处理 (NLP) 的技术演变史

一、简述 本文的目标是了解自然语言处理 (NLP) 的历史,包括 Transformer 体系结构如何彻底改变该领域并帮助我们创建大型语言模型 (LLM)。 基础模型(如 GPT-4)是最先进的自然语言处理模型,旨在理解、生成人类语言并与之交互。 要理…

C#语法知识之循环语句

5、循环语句 文章目录 1、while思考1 斐波那契数列思考2 判断一个数是否为质数思考3 找出100以内的质数 2、do...while3、for思考1 找水仙花数思考2 乘法表 1、while 1、作用 让代码重复去执行 2、语法相关 while(bool类型值){//当满足条件时,就会执行while语句…

K8S哲学 - Pod、RC、RS、deployment

pod(最小的可部署单元) 容器组(运行一个或多个容器) Pod(容器组)是Kubernetes 中最小的可部署单元。 一个Pod(容器组)包含了一个应用程序容器(某些情况下是多个容器)、存储资源、 一…

Java高阶私房菜:高并发之线程池底层原理学习

以往我们需要获取外部资源(数据源、Http请求等)时,需要对目标源创建链接对象,三次握手成功后方可正常使用,为避免持续的资源占用和可能的内存泄漏,还需要调用目标对象close方法释放资源销毁对象。这一建一销…

墨子web3实时周报

蚂蚁集团Web3研发进展与布局 国内Web3赛道的领军企业——蚂蚁集团,凭借其在前沿科技领域的深耕不辍,已在Web3技术研发疆域缔造了卓越战绩。特别是在引领行业革新的关键时刻,集团于今年四月末震撼推出了颠覆性的Web3全套解决方案,…

Vue+OpenLayers7入门专栏目录,OpenLayers7中文文档,OpenLayers7中文手册api,OpenLayers7中文教程

返回入门到实战汇总目录:汇总目录 前言 本篇作为《VueOpenLayers7入门教程》所有文章的二合一汇总目录,方便查找。 本专栏源码是由OpenLayers7.x版本结合Vue框架编写。本专栏基本上每章都有详细的源代码和运行示例以供参考,且保证每章代码都…

git远程分支强制覆盖本地分支

目录 第一章、问题1.1)报错提示:没有为分支主机或分支配置被跟踪的分支1.2)报错分析与解决 第二章、2.1)本地误删代码后想要git pull拉取覆盖:失败2.2)报错分析和解决 友情提醒: 先看文章目录,…

《设计模式之美》- 总结

《设计模式之美》- 总结 第一章 概述 1.1 为什么学习代码设计 编写高质量的代码应对复杂代码的开发程序员的基本功职业发展的必备技能 1.2 如何评价代码的质量 1.2.1 可维护性 可维护性代码的特性:代码简洁、可读性好、可扩展性好代码分层结构清晰、模块化程度…

SQLite FTS3 和 FTS4 扩展(三十二)

返回:SQLite—系列文章目录 上一篇:SQLite 的命令行 Shell(三十一) 下一篇:SQLite—系列文章目录 概述 FTS3 和 FTS4 是 SQLite 虚拟表模块,允许用户执行 对一组文档进行全文搜索。最常见(和最有效…

「51媒体」新闻媒体邀约如何进行媒体宣传(方法)

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 新闻媒体邀约进行媒体宣传是一个策略性的过程,旨在吸引媒体的注意力并促使其对特定事件、产品发布或企业活动进行报道。以下是一些关键步骤和策略: 制定媒体传播方…