文章目录
缓存雪崩、击穿、穿透
使用redis作为缓存,相当于数据缓存在内存,大大提高系统性能
1.缓存雪崩
造成缓存雪崩
-
大量缓存数据在同一时间过期
-
redis故障宕机
若此时有大量用户请求,无法在redis处理,都直接访问数据库 => 数据库压力骤增(严重造成数据库宕机) => 形成一系列连锁反应 => 整个系统崩溃
解决缓存雪崩
=> 大量缓存数据在同一时间过期时:
-
互斥锁(当业务线程在处理用户请求时,如果发现访问的数据不在redis里,加互斥锁,保证同一时间内只有一个请求来构建缓存(从数据库读取数据,再将数据更新到redis),当缓存构建完成后,再释放锁。)
注:互斥锁设置超时时间,否则若出现请求发生意外阻塞,导致其他请求也一直拿不到锁 -
后台更新缓存(让缓存“永久有效”,将更新缓存的工作交由后台线程定时更新)
当系统内存紧张时,有些缓存数据被“淘汰”,在“淘汰”和下次更新时间内,业务线程读取失败就以为是数据丢失,解决方法:
=> Redis故障宕机时:
-
服务熔断:暂停业务应用对缓存服务的访问,直接返回错误,不再继续访问数据库,直到redis恢复正常。
请求限流机制:只将少部分请求发送到数据库进行处理,再多的请求就在入口直接拒绝服务,等到Redis恢复正常 并把缓存预热完后。
2. 缓存击穿
造成缓存击穿
被频繁访问的热点数据过期,此时大量的请求访问该热点数据,直接访问数据库,数据库很容易被高并发的请求冲垮
缓存击穿可以认为是缓存雪崩的一个子集(对应于大量缓存数据在同一时间过期)
解决缓存击穿
3.缓存穿透
对于缓存雪崩、击穿,数据仍然在数据库,一旦缓存恢复相应的数据,就可以减轻数据库的压力
而对于缓存穿透:
用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存缺失,再去访问数据库,发现数据库也没有要访问的数据,没办法构建缓存来服务后续请求。当有大量的这样的请求时,数据库的压力骤增
造成缓存穿透
解决缓存穿透
-
非法请求的限制
-
缓存空值或默认值
当线上业务发现缓存穿透时,针对查询的数据,在缓存中设置一个空值或默认值,后续请求可以从缓存中读取到数据,而不会继续查询数据库
-
使用布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断数据是否存在。
写入数据库数据时,使用布隆过滤器做标记,当业务线程确认缓存失效后,可以通过查询布隆过滤器判断数据是否存在。(大量请求只会查询布隆过滤器和redis,而不会查询数据库)
注:布隆过滤器的实现
将该数据x得到的三个哈希值 % 位图数据长度得到三个数组下标,填入1。
当业务线程查询数据是否存在于数据库时,查询 1、4、6下标的值是否为1,若有一个为0,则说明不存在
(存在哈希冲突,故若查询布隆过滤器说数据存在于数据库,此时数据不一定在数据库;但是查询到数据不存在时,数据一定不存在)
更新数据时,如何保证数据库和缓存的一致性?
1. 先更新数据库?先更新缓存?
在数据更新时,先更新数据库还是先更新缓存,都会存在并发问题,当两个请求并发更新同一条数据时,可能会出现缓存和数据库中数据不一致的现象。
解决方案
2. Cache Aside策略
旁路缓存策略: 在更新数据时,不更新缓存,更新数据库,删除缓存, 当读取数据发现缓存中无该数据时,再从数据库中读取数据,并且写入缓存。
分为读策略、写策略
例:请求A读取数据,请求B更新数据
此时数据库中为21,缓存中为20
① 先更新数据库,再删除缓存
故 先更新数据库,再删除缓存 可以保证“数据一致性”,并且对缓存加上过期时间,可以保证最终一致性
问题:
-
先更新数据库,再删除缓存会导致缓存命中率降低。
若对缓存命中率有要求,可以采用更新数据库+更新缓存,解决方案见1.
-
这种方法保证数据一致性的前提是 更新数据库和删除缓存都能正常执行成功。
(删除缓存失败时,可能出现缓存中为旧数据,数据库中为新数据)
保证更新数据库、删除缓存都执行成功
采用异步缓存,保证第二个操作执行成功
② 先删除缓存,再更新数据库
出现并发问题,造成缓存、数据库数据不一致
解决方案
延迟双删
- 删除缓存
- 更新数据库
- 睡眠
- 再删除缓存
请求A在睡眠时,B能够完成读取数据库数据,并把缺失数据写入缓存,A睡眠完后删除缓存。
请求A的睡眠时间 > 请求B的从数据库读取数据+写入缓存的时间
该方案尽可能保持一致性,建议采用先更新数据库,再删除缓存
互斥锁:单机情况下,内存中的一个互斥锁就能控制一个程序的线程并发
分布式锁:适用于分布式场景,集群架构,需要“全局锁”实现控制多个程序/多个机器上的线程并发
原文地址:https://blog.csdn.net/liaoai/article/details/134561705
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_2137.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!