Redis(2) 雪崩、击穿、穿透

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

  • 随着移动互联⽹的快速发展,互联⽹的⽤户数量越来越多,产⽣的数据规模也越来越⼤,对数据库也提出了更⾼的要求,为了减少直接访问数据库,我们会⽤ Redis 作为缓存层。
    -请添加图片描述
  • 因为 Redis 是内存数据库,我们可以将数据库的数据缓存在 Redis ⾥,相当于数据缓存在内存,内存的读写速度⽐硬盘快好⼏个数量级,这样⼤⼤提⾼了系统性能。
  • 在今天的互
    联⽹⾥,⾼并发、⼤数据量、⼤流量已经成为了代⾔词,那么我们的系统也承受着巨⼤的压⼒,⾸当其冲的解决⽅案就是 redis 。
  • redis 使⽤不当就会产⽣雪崩、穿透、击穿等问题

请添加图片描述

一、缓存雪崩

通常: 为了保证缓存中的数据与数据库中的数据⼀致性,会给 Redis ⾥的数据设置过期时间,当缓存数据过期后,⽤户访问的数据如果不在缓存⾥,业务系统需要重新⽣成缓存,因此就会访问数据库,并将数据更新到Redis ⾥,这样后续请求都可以直接命中缓存。
请添加图片描述

雪崩原因: ⼤量数据同时过期 / Redis 故障宕机

请添加图片描述

  • 当⼤量缓存数据在同⼀时间过期(失效)或者 Redis 故障宕机时,这时⼤量的⽤户请求,就直接访问到数据库了,从⽽导致数据库的压⼒骤增,严重的会造成数据库宕机,从⽽造成整个系统崩溃,这就是造成缓存雪崩的原因。
  • 总结:在⾼并发下,⼤量缓存 key 在同⼀时间失效,⼤量请求直接落在数据库上,导致数据库宕机。

解决方法:

  • ⼤量数据同时过期时 解决方法:
方法解释
均匀设置过期时间避免将⼤量的数据设置成同⼀个过期时间。在对缓存数据设置过期时间时,给这些数据的过期时间加上⼀个随机数,这样就保证数据不会在同⼀时间过期。
互斥锁请求时,如果发现访问的数据不在 Redis ⾥,就加个互斥锁,保证同⼀时间内只有⼀个请求来构建缓存,但容易阻塞,系统会出现无响应现象
双 key 策略对缓存数据可以使⽤两个 key ,⼀个是主 key ,会设置过期时间,⼀个是备 key ,不会设置过期。当业务线程访问不到 主key 的缓存数据时,就直接返回 备key 的缓存数据,然后在更新缓存的时候,同时更新 主key 和 备key 的数据。
后台更新缓存业务线程不再负责更新缓存,缓存也不设置有效期,⽽是让缓存“永久有效”
  • Redis 故障宕机 解决方法:

① 服务熔断或请求限流机制(雪崩发⽣后的应对⽅案)

服务熔断机制:(全部业务都⽆法正常⼯作)
暂停业务应⽤对缓存服务的访问,直接返回错误,不⽤再继续访问数据库,从⽽降低对数据库的访问压⼒,保证数据库系统的正常运⾏,然后等到Redis 恢复正常后,再允许业务访问缓存服务。

请求限流机制:(减少对业务的影响)
只将少部分发送到数据库进⾏处理,再多的请求就在⼊⼝直接拒绝服务,等到 Redis 恢复正常并把缓存预热完后,再解除请求限流的机制。

② 构建 Redis 缓存⾼可靠集群

通过主从节点的⽅式构建 Redis 缓存⾼可靠集群。
如果 Redis 缓存的主节点故障宕机,从节点可以切换成主节点,继续提供缓存服务,避免了由于 Redis 故障宕
机⽽导致缓存雪崩问题。

二、缓存击穿

**击穿原因:**如果缓存中的某个热点数据(被频繁地访问的数据)过期了,此次⼤量的请求访问了该热点数据,就⽆法从缓存中读取,直接访问数据库,数据库很容易就被⾼并发的请求冲垮,这就是缓存击穿的问题。(可以认为缓存击穿是缓存雪崩的⼀个⼦集)

解决方法:

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

三、缓存穿透

穿透原因:
当⽤户访问的数据,既不在缓存中,也不在数据库中,导致请求访问缓存时,发现缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据,⽆法构建缓存数据来服务后续的请求。那么当有⼤量这样的请求到来时,数据库的压⼒骤增,这就是缓存穿透的问题。

  • 业务误操作,缓存中的数据和数据库中的数据都被误删除了,所以导致缓存和数据库中都没有数据。
  • ⿊客恶意攻击,故意⼤量访问某些读取不存在数据的业务。

解决方法

方法解释
⾮法请求的限制在 API ⼊⼝处我们要判断请求参数是否合理,请求参数是否含有⾮法值、请求字段是否存在,如果判断出是恶意请求就直接返回错误,避免进⼀步访问缓存和数据库。
缓存空值或者默认值针对查询的数据,在缓存中设置⼀个空值或者默认值,这样后续请求就可以从缓存中读取到空值或者默认值,返回给应⽤,⽽不会继续查询数据库。
布隆过滤器使⽤布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断数据是否存在。我们可以在写⼊数据库数据时,使⽤布隆过滤器做个标记,缓存穿透时,可以通过查询布隆过滤器快速判断数据是否存在,如果不存在,就不⽤通过查询数据库来判断数据是否存在。

总结

雪崩是⼤⾯积的 key 缓存失效;
穿透是 Redis ⾥不存在这个缓存 key ;
击穿是 Redis 某⼀个热点 key 突然失效,最终的受害者都是数据库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值