redis:缓存雪崩、击穿、穿透、一致性

本文探讨了Redis作为缓存时可能遇到的缓存雪崩、缓存击穿和缓存穿透问题,介绍了相应的解决策略,如设置随机过期时间、互斥锁、服务熔断和使用布隆过滤器,以及如何保持数据一致性,包括延迟删除和先数据库后缓存的更新顺序。
摘要由CSDN通过智能技术生成

尽管redis很牛但是因为是在内存中的所以存储的数据量总是有限的,所以常常作为数据库的缓存,作为缓存的时候就要考虑缓存的实际捕获效果和数据一致性。

缓存雪崩

由于缓存资源是有限的所以我们常常需要为缓存设置过期时间,当大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩的问题。

造成缓存雪崩和对应的解决方式如下:

大量缓存同时失效:

  • 均匀设置过期时间,过期时间取一个随机数
  • 互斥锁,如果发现访问的数据不在 Redis 里,就加个互斥锁,保证同一时间内只有一个请求来构建缓存,这样可以减少对同一资源的大量请求数据库,这里最后设置锁的过期时间,不然第一个请求失效的话过一段时间还可以有下一个请求而不会宕机
  • 后台更新缓存,业务线程不再负责更新缓存,缓存也不设置有效期,而是让缓存“永久有效”,并将更新缓存的工作交由后台线程定时更新,靠缓存淘汰机制更新缓存
    • 后台线程不仅负责定时更新缓存,而且也负责频繁地检测缓存是否有效,检测到缓存失效了,原因可能是系统紧张而被淘汰的,于是就要马上从数据库读取数据,并更新到缓存,延迟较高效果不太好
    • 业务线程发现缓存丢失,告诉后台线程更新缓存,比较及时效果较好

redis宕机

  • 服务熔断或请求限流机制,redis宕机的时候直接关闭redis服务,减少数据库压力
  • 构建 Redis 缓存高可靠集群,以主从节点的方式构建 Redis 缓存高可靠集群。

缓存击穿

对热点数据如果访问量很大的时候缓存失效数据库会被大量相同的数据请求直接搞宕机,解决起来可以考虑对资源请求加锁,每次访问不到缓存只放一个请求过去,其它对相同资源的请求则拦截在外,或者说想办法延长这些数据的失效时间。

  • 互斥锁方案,保证同一时间只有一个业务线程更新缓存,未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。
  • 不给热点数据设置过期时间,由后台异步更新缓存,或者在热点数据准备要过期前,提前通知后台线程更新缓存以及重新设置过期时间;

缓存穿透

简单的理解的话就是数据即不在缓存也不在数据库,触发情景一般不太对劲,比如:

  • 数据被误删了
  • 服务器被黑客攻击了

解决起来很简单

  • 访问前看数据存在不,不存在返回空
  • 发现出现穿透现象的时候对查询的数据设置空缓存,让它返回空
  • 使用布隆过滤器快速判断数据存在不,简单来说布隆过滤器的原理就是位图+哈希,对数据哈希后将得到的哈希值对应的位置为1,这样就可以快速判断数据存在不了

缓存和数据库如何保持数据一致性?

首先只有并发的进行读写操作的时候才会存在数据不一致情况,实际上redis的数据一致性是最终一致性而不是强一致性,面对写操作有两种情景先操作缓存/先操作数据库。

先操作缓存

  • 先删除缓存再更新数据库,这时候另一个线程请求这个资源由于网络原因读到了修改前的数据同时建立了缓存,这时候就会遇到数据不一致。
    解决方法:延时双删,更新数据库后延时再次删除,可以有效删除由于网络延时造成的脏数据缓存,但是还是会造成一段时间内数据不一致,或者对资源加锁,遇到写操作阻塞资源访问,实现强一致性,但是影响并发性。

先操作数据库

  • 先更新数据库中的数据再删除对应缓存,删除缓存前访问的都是老数据,如果删除缓存失败会遇到长时间的数据不一致
    解决办法:循环删除,删除失败时给重删模块发送消息,它进行再次删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值