Java开发-面试题-0008-Redis 缓存穿透、缓存击穿、缓存雪崩
更多内容欢迎关注我(持续更新中,欢迎Star✨)
Github:CodeZeng1998/Java-Developer-Work-Note
技术公众号:CodeZeng1998(纯纯技术文)
生活公众号:好锅(Life is more than code)
CSDN: CodeZeng1998
其他平台:CodeZeng1998、好锅
Redis 作为我们经常使用的缓存服务,Redis 有几个经典问题就是关于缓存穿透、缓存击穿、缓存雪崩的下面我们就开介绍一下这三种现象出现的原因以及对应的解决办法。
缓存穿透
原因:缓存穿透是指查询一个不存在的数据,由于缓存中没有数据,会直接穿透到数据库进行查询。通常发生在查询条件恶意构造的情况,如大量查询不存在的用户 ID。
解决办法:
- 方案一:缓存空数据,查询返回的数据为空,仍把这个空结果进行缓存。
- 优点:能够有效防止对不存在数据的重复查询,简单易实现。
- 缺点:会占用额外的缓存空间,如果大量不存在的键被查询,会导致缓存空间的浪费。
- 方案二:布隆过滤器(Bloom Filter)
- 优点:能够高效地判断一个数据是否存在,内存占用小。
- 缺点:实现复杂,存在误判,有一定的误判率(即可能会误判某些不存在的数据为存在),需要提前构建过滤器
布隆过滤器
bitmap(位图):相当于是一个以(bit)位为单位的数组,数组中每个单元只能存储二进制数0或1
布隆过滤器作用:布隆过滤器可以用于检索一个元素是否在一个集合中。
- 存储数据:id为1的数据,通过多个hash函数获取hash值,根据hash计算数组对应位置改为1
- 查询数据:使用相同hash函数获取hash值,判断对应位置是否都为1
误判率:数组越小误判率就越大,数组越大误判率就越小,但是同时带来了更多的内存消耗。
缓存击穿
原因:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮。
解决办法:
-
方案一:互斥锁
-
优点:能够有效防止缓存击穿,确保只有一个线程能查询数据库。
缺点:增加了请求的延迟,锁的管理和维护也有一定的复杂性。
-
-
方案二:提前续约
-
优点:在缓存失效前刷新缓存,能够有效防止缓存击穿。
缺点:需要定时任务来刷新缓存,增加了一定的复杂性和系统开销。
-
-
方案三:逻辑过期
-
优点:实现简单方便,只需要增加一个属性标识过期时间即可。
缺点:逻辑过期的数据依然能够使用。
-
-
方案四:热点数据永不过期
- 优点:对热点数据设置永不过期,能彻底避免缓存击穿。
- 缺点:需要手动管理和更新缓存,可能会导致缓存数据过时。
缓存雪崩
原因:缓存雪崩是指缓存系统中大量数据在同一时间过期或Redis服务宕机,导致大量请求直接打到数据库,瞬间对数据库产生巨大压力。
解决办法:
-
缓存过期时间随机化:
- 优点:通过随机化过期时间,避免大量缓存同时失效,简单易实现。
- 缺点:不能完全杜绝缓存雪崩,只能降低概率。
-
双缓存策略:(给业务添加多级缓存(Guava或Caffeine))
- 优点:主从缓存配置能够提高系统的容灾能力,在缓存失效时有备用方案。
- 缺点:实现和维护复杂度较高,增加了系统开销。
-
限流降级:(给缓存业务添加降级限流策略(nginx或spring cloud gateway))
- 优点:能够在缓存不可用时有效保护数据库,保证系统的稳定性。
- 缺点:需要设计和实现限流策略,可能会影响用户体验。
-
Redis集群部署:(利用Redis集群提高服务的可用性(哨兵模式、集群模式))
- 优点:提高了缓存的高可用性和容灾能力,分散了请求压力。
- 缺点:增加了系统架构的复杂性和成本,需要专业的运维和管理。
以上就是对 Redis 的缓存穿透、缓存击穿、缓存雪崩的介绍以及解决办法了。
上图是由 Pic 生成的
关键词:A big tree grows in the sky, and birds run on the ground
更多内容欢迎关注我(持续更新中,欢迎Star✨)
Github:CodeZeng1998/Java-Developer-Work-Note
技术公众号:CodeZeng1998(纯纯技术文)
生活公众号:好锅(Life is more than code)
CSDN: CodeZeng1998
其他平台:CodeZeng1998、好锅