redis面试篇--使用场景

本章面试内容:

一、使用场景

1、缓存

2、分布式锁

一、使用场景

1、缓存

面试官:什么是缓存穿透?怎么解决?
答:查询数据的过程是,请求先到redis中去查询数据,存在就返回数据,不存在就到数据库DB中去查询数据,并将返回的数据缓存到redis中。
缓存穿透:就是查询一个一定不存在的数据,每次请求都会请求到数据库,当一瞬间这样的请求并发大的时候,大量的并发请求到数据库,可能会导致数据库DB宕机。一般这样的情况发生,大概率是遭到了攻击。
(比如查询 id = -1 的数据)

解决方案:

1、缓存 null 值,在redis中缓存 null ,缺点是需要消耗内存。

2、在查询 redis 之前,利用布隆过滤器判断数据是否存在,可能存在误差。

面试官:解释一下 布隆过滤器。

答:布隆过滤器 主要是用来检查一个元素是否在一个集合中,在项目中使用的是redisson实现的布隆过滤器。

布隆过滤器底层,先初始化一个比较大的数组,一开始这个数组里全是 0 ,当一个key来了后经过三次hash计算,并模于数组的长度,得到数组中的三个坐标,将对应坐标上的数字 0 改为 1 ,这样数组中的三个坐标就可以表示一个key的存在,查询的过程也一样。

缺点:存在误差,会产生一定的误差,一般可以设置这个误差在 5% 以内,一般项目是可以接受的,这样当大量的并发过来的时候不至于压倒数据库DB。如果要减小误差,就得扩大底层数组的长度,这样又会更消耗内存。

面试官:什么是缓存击穿?怎么解决?

缓存击穿:缓存击穿的意思是,对于设置了过期时间的key,某个时间这个key刚好过期了,这个时候,恰好这个key有大量的并发请求过来,这些请求发现缓存过期,一般都会去数据库中加载数据,并回设缓存到redis,可能会瞬间压垮数据库。

两种解决方案:

一、使用互斥锁:

当缓存失效的时候,不立即去 查询数据库,加载缓存,先使用redis的setnx设置一个互斥锁,再去数据库加载数据,并缓存数据到redis,否则重试get缓存方法。

二、设置key逻辑过期:

1、在设置key的时候,设置一个过期字段,不给当前的key设置过期时间。

2、当查询的时候,从redis取出数据判断当前key是否过期。

3、如果当前的key过期了,开通另一个线程进行数据同步,当前线程正常返回数据,这个数据不是最新的。

两种方案的优缺点:

强一致性选择互斥锁的方案,性能上可能没那么高,因为锁需要等待,也可能会产生死锁。

高可用选择key逻辑过期,性能比较高,但是数据同步做不到强一致。

面试官:什么是缓存雪崩?怎么解决

缓存雪崩:设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到数据库DB,数据库瞬间压力过大,导致雪崩,与缓存击穿的区别,雪崩时同一时刻大量的key过期,击穿是一个key。

解决方案:

1、将缓存失效的时间分开,比如在原来过期时间的基础上添加一个随机时间。避免key集体失效。

2、如果是redis宕机,导致并发请求到数据库,可以给redis做成集群模式,哨兵模式。

3、给缓存业务添加降级限流策略,比如在nginx,gateway添加限流策略。

4、给业务添加多级缓存。让redis作为二级缓存。

面试官:redis作为缓存,mysql的数据和redis的数据如何同步?(双写一致性)。

正常情况下:

读数据:请求redis数据命中,返回数据,未命中,到数据库查数据并,回设缓存。

写操作(延迟双删):删除缓存 --->操作数据库--->删除缓存

操作数据的时候出现的问题:

1、先操作redis:

线程1 删除缓存 --- 线程1 修改数据库数据为10 --- 线程2 查询缓存 --- 未命中 ---线程2查询数据库,查到 数据10 --- 缓存重建,回设缓存数据为10。这是正常情况。

假设:线程1 删除缓存 ---  线程2 查询缓存 --- 未命中,没查到数据  ---  线程2 查询数据库数据为10 --- 线程2 回设缓存为10  ---   线程1 修改数据库数据为20。这时数据库数据20、缓存数据10,数据不一致,出现脏数据。

2、先操作数据库:

线程1 修改数据库数据为20  ---  线程1 删除缓存 。线程2 查询缓存  ---  未命中,线程2 查询数据库数据20  ---  线程2 回设缓存。这是正常情况。

假设:线程1 查询缓存  --- 未命中  ---  线程1 查询数据库,得到数据 10  ---  线程2 更新数据库数据为20  ----  线程2 删除缓存  ---  线程1 回设缓存为10。这时候数据库数据 20,缓存数据 10 ,数据不一致出现脏数据。  

三个问题:

1、先删除缓存还是先删除数据库。

答:都不行,因为可能会出现脏数据。上面有分析。

2、为什么要删除两次缓存。

答:避免产生脏数据。

3、为什么要延时删除。

答:因为数据库一般是主从读写分离的方式。主从同步的时候有一定延时,这个延时的过程中可能会出现脏数据。

三种解决方案:

1、添加互斥锁的方式:

线程1 加锁 --- 线程1 写数据  --- 线程1 删除缓存  ---线程1 释放锁。

线程2 加锁 --- 线程2 读缓存,未命中  --- 线程2 读数据库  --- 线程2 更新缓存  --- 线程2 解锁。 

优化:读写锁(redisson),共享锁(读读不互斥,读写互斥),排他锁(读读互斥,读写互斥)

采用redisson的读写锁,在读数据的时候添加共享锁,在写数据的时候添加排他锁,这样就能保证在写数据的同时,不让其他线程读取数据。避免脏数据的出现,注意,读方法和写方法需要使用同一把锁。

2、MQ异步通知的方式

操作数据库的服务、操作redis缓存的服务、MQ

数据库更新时,向MQ发送通知,缓存的服务监听MQ,更新缓存。数据同步有一定的延迟,但是最终数据一致。还要MQ消息的可靠性。

3、cannal异步通知的方式

操作数据库的服务、cannal组件、数据库的binlog日志文件

cannal服务把自己伪装成mysql的一个从节点,当数据库更新时,cannal读取binlog数据,然后通过cannal客户端获取数据,更新缓存。  

cannal组件实现数据同步,不需要更改业务代码。

面试官:你听说过延时双删吗?为什么不用它?

答:延迟双删,如果时写操作,先删除缓存,然后更新数据库,最后在延时删除缓存。其中这个延时多久时间不好确定,在延时的过程中,可能会出现脏数据,并不能保证强一致性,所以没有采用它。

面试官:redis作为缓存,数据的持久化是怎么做的?

redis提供两种持久化方式:

1、RDB 数据备份文件

2、AOF 追加文件

面试官:RDB,AOF两种持久化方式有什么区别

1、RDB 是数据备份文件,将redis内存中的数据写到磁盘上,当redis宕机的时候通过RDB文件来恢复数据。RDB文件是二进制文件,体积小。恢复数据速度快。

2、AOF 是追加文件,redis操作写命令的时候,都会存储在这个文件中,当redis宕机的时候,恢复数据的时候,会在执行一遍文件中的命令,恢复数据。

面试官:两种方式,哪种方式恢复的比较快。

RDB是二进制文件,在保存数据的时候,体积也是比较小的,他恢复的比较快,但是它可能会丢数据。

AOF是追加文件,恢复数据的时候可能会慢一些,但是丢数据的风险小。在AOF文件中可以设置刷盘策略,一般设置为 everysec 每秒批量写入一次命令。

always 同步刷盘

everysec 每秒刷盘

no 操作系统控制

面试官:redis的数据过期策略有哪些?数据过期会立马删除吗?(不会)

答:redis的数据过期策略有两种

一、惰性删除

用到key的时候,在检查这个key是否过期,过期了就删除,没有过期就返回数据。

优缺点:这种方式对cpu友好,对内存不友好。只有用到的时候检测是否过期,不用的时候就在内存中不做处理。会浪费内存空间。

二、定期删除

每个一段时间定期检查内存中的key是否过期,过期了就删除。(这种方式只对一部分的key做检查,并不是检查所有的key)

两种模式的定期删除策略:

show模式:

show模式是定时任务,执行频率10hz,每秒10次,每次执行时间不超过25ms,可以通过修改redis.conf的hz选项来调整次数。

fast模式:

执行频率不固定,每次事件循环都会尝试执行,两次间隔不超过2ms,每次耗时不超过1ms。

优点:

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

缺点:

难以确定删除操作执行的时常和频率。

redis的过期删除策略:

惰性删除+定期删除两种策略结合使用

面试官:假设缓存过多,内存有限,内存满了怎么办。(删除内存中过期的key,释放内存)

面试官:数据淘汰策略

当redis中内存不够时,这时候在向redis中添加数据,redis就会按照某种规则删除内存中的数据,这种删除数据的规则就是数据淘汰策略。

数据淘汰策略有8种:

1、noeviction:不淘汰任何的key,但是内存满了以后,向redis中添加数据就会报错。这个是redis中默认的策略。

2、volatitle-ttl:对设置了ttl过期时间的key,比较其剩余的时间,ttl剩余的时间越少,优先淘汰。

3、allkeys-random:对全体的key进行随机的淘汰。

4、volatitle-random:对设置了过期时间的key进行随机淘汰

lru或lfu算法随机淘汰
 

5、allkeys-lru:对所有的key,采用 lru 算法淘汰。

6、volatitle-lru:对设置了有效时间的 key 进行lru淘汰。

7、allkeys-lfu:对全体key,基于lfu算法淘汰。

8、volatitle-lfu:对设置了有效时间的key基于lfu淘汰。

面试官:reids数据淘汰策略有哪些?

redis的淘汰策略有很多,默认淘汰策略为 noeviction 当内存不足的时候,向redis添加数据,会直接报错。

淘汰策略可以在redis.conf中进行配置,这里有两个重要的概念。

LRU:最近最少访问,用当前时间减去最近时间,这个值越大,淘汰的优先级越高。

LFU:最少频率访问,对全体的key做使用频率统计。值越小,淘汰的优先级越高。

在项目中一般使用的是的 allkeys-LRU,挑选最近最少使用的kye进行淘汰,将一些常用的key留在redis中。

面试官:数据库中有100W 条数据,但是redis中只能存储 20 W的数据,如何保证redis中缓存的数据都是热点数据。

可以在redis.conf 配置文件中设置数据淘汰策略为,allkeys-lru(挑选最近最少使用的数据淘汰)。这样就可以保证redis中缓存的数据都是热点数据。

面试官:redis的内存使用完了会发生什么?

答:这要看redis使用的数据淘汰策略是什么,默认情况下,redis的数据淘汰策略是noeviction,这时redis的内存使用完了,会直接报错。一般在项目中会配置redis的数据淘汰策略为 allkeys-lru,这种数据淘汰策略可以保证redis中缓存的数据是热点数据,当内存不够的时候,redis会按照lru算法,去内存中挑选最近最少使用的数据优先淘汰。

面试官:redis分布式锁怎么实现

redis中提供了一个命令,setnx(set if not existes)

由于redis是单线程的,使用了这个命令后,就只能有一个客服端对这个key设置值。如果这个key没有过期,或者这个key没有删除,其他客服端不能设置这个key的值。

面试官:如何控制redis分布式锁的有效时常

redis提供的setnx不好控制,这个时候可以使用redis的一个框架redisson控制锁的有效时常。

在redisson中需要手动加锁,来控制锁的有效时常,和等到时间。在redisson中还有一个看门狗机制,就是说每隔一段时间,就检查当前业务是否还持有锁,如果持有锁,就会刷新锁持有的时间。业务执行完毕后就释放锁。

另一方面,如果是在高并发的情况下。一个业务可能执行的很快,一开始客户1先持有锁进行业务操作,这时候客户2 来了,也想要持有锁,并不会被马上拒绝,而是继续自旋尝试获取锁。当客户1执行完业务释放锁的时候,客户2 就可以立即获得锁。性能也得到提高。

面试官redisson实现的分布式锁可以重入吗?

答:可以重入,这样做是为了避免产生死锁。其实是在内部判断是否是统一个线程,如果是同一个线程就可以重入,不是就拒绝重入。当前线程再次持有锁就计数 +1 ,释放锁就计数 -1 。存储数据采用hash结构,大key可以自定义,小key表示当前线程的id,value表示当前线程重入的次数。

面试官:redis实现的分布式锁能解决主从一致的问题吗?

答:不能,假设线程1 加锁成功,master节点的数据异步复制到slave节点,此时master节点宕机了,slave节点成为新的master节点,线程2 加锁,会在新的master节点加锁成功,这时候就会出现两个线程同时持有一把锁。

redisson中有红锁的机制,当master节点宕机的时候,某个slave会成为新的master节点,其他的slave节点会到新的master上同步数据。old master上就没有了slave。线程到master加锁的时候,就会判断当前的master上是否有slave,没有加锁失败。

但是,如果使用红锁,就要在多个节点上加锁,性能会变低,维护成本也高,官方也不推荐这样的方式。一般项目中也不会使用这样的方式。(可以使用zookeeper实现的分布式锁,来解决这个问题)。

面试官:如果业务要保持强一致性,这个问题要怎么解决。

答:redis本身支持高可用,如果有强一致性要求高的业务,可以使用zookeeper的分布式锁,它可以保证数据的强一致性。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、什么是 Redis?简述它的优缺点? 2、Redis 相比 memcached 有哪些优势? 3、Redis 支持哪几种数据类型? 4、Redis 主要消耗什么物理资源? 5、Redis 的全称是什么? 6、Redis 有哪几种数据淘汰策略? 7、Redis 官方为什么不提供 Windows 版本? 8、一个字符串类型的值能存储最大容量是多少? 9、为什么 Redis 需要把所有数据放到内存中? 10、Redis 集群方案应该怎么做?都有哪些方案? 11、Redis 集群方案什么情况下会导致整个集群不可用? 12、MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 13、Redis 有哪些适合的场景? 14、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个? 15、RedisRedisson 有什么关系? 16、Jedis 与 Redisson 对比有什么优缺点? 17、Redis 如何设置密码及验证密码? 18、说说 Redis 哈希槽的概念? 19、Redis 集群的主从复制模型是怎样的? 20、Redis 集群会有写操作丢失吗?为什么? 21、Redis 集群之间是如何复制的? 22、Redis 集群最大节点个数是多少? 23、Redis 集群如何选择数据库? 24、怎么测试 Redis 的连通性? 25、Redis 中的管道有什么用? 26、怎么理解 Redis 事务? 27、Redis 事务相关的命令有哪几个? 28、Redis key 的过期时间和永久有效分别怎么设置? 29、Redis 如何做内存优化? 30、Redis 回收进程如何工作的?
回答: Redis在实际应用中有多种使用场景。首先,由于Redis是基于内存的数据库,读写速度非常快,因此它经常被用作缓存系统,可以显著提高系统的性能。其次,Redis支持发布订阅模式,可以用于构建消息系统,实现实时的消息传递。此外,Redis还可以用作定时器和计数器,用于统计和计算数据。\[1\] Redis还具有多种功能,包括支持不同数据类型的存储和操作,如字符串、列表、集合、有序集合和哈希表。它还支持事务、持久化、LUA脚本、LRU驱动事件和多种集群方案。\[3\] Redis在6.0版本之前是单线程的,但在6.0版本之后开始支持多线程,以提高网络IO处理的性能。\[2\] Redis的持久化方式有两种,一种是RDB持久化,将数据快照保存到磁盘上,另一种是AOF持久化,将每个写操作追加到文件中。\[2\] 总的来说,Redis在缓存、消息系统、计数器和定时器等场景中有广泛的应用。 #### 引用[.reference_title] - *1* *2* [redis面试题总结(附答案)](https://blog.csdn.net/guorui_java/article/details/117194603)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [史上最全redis面试题及答案吊打面试官](https://blog.csdn.net/love468092550/article/details/116305836)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值