自学内容网 自学内容网

缓存穿透/击穿/雪崩(附生产BUG)

优质博文:IT-BLOG-CN

一、背景

为什么要写这篇文章?
生产缓存生成服务转java时,需要通过配置文件进行流量切换。开发人员同时打开了两个配置页面。原配置信息=ABCDEF。在第一个配置页面进行缓存切换,添加G业务缓存,配置信息=ABCDEFG。随后H业务也需要进行缓存切换,但开发人员在第二个配置页面添加了H,配置信息=ABCDEFH导致第一次添加的G业务写缓存丢失。随着时间的推移8分钟后G业务缓存陆续过期,造成缓存雪崩

为什么保存配置和审核配置的时候没有发现异常
切流量设计10多种业务需要修改20多次配置,操作上惯性认为页面刷入是最新的版本,没有逐一进行检查。

监控为什么没有及时告警
监控比较滞后,目前监控的指标比较粗粒度,只有缓存过期后,导致订单量下降才会进行告警。同时缓存命令率的监控也是10分钟后直接掉至0

影响的单量
影响订单300单,并立即回滚配置信息。

二、缓存雪崩

大量的key设置了相同的过期时间,或者因为Redis实例宕机,在同一时刻缓存全部失效,造成请求全部穿透到DB,瞬时DB请求量大、压力骤增,可能导致DB被打挂。

解决方案:
【1】过期时间打散: 避免大量key同时过期,可以在设置过期时间时,在基础过期时间上加一个随机值来打散过期时间,通过打散过期时间,避免同一时间大量缓存过期。
【2】不过期: 不为数据设置过期时间或者设置比较长的过期时间,由专门的job应用定时刷新缓存。
【3】Redis高可用: 通过主从复制,故障转移等高可用机制避免 Redis 集群不可用导致的缓存雪崩。
【4】数据库限流与熔断: 对数据库的读添加限流与熔断机制,目的主要是为了在无可避免的缓存雪崩时保护数据库,使得之后能快速恢复缓存。
【5】数据库解耦: 应用完全与数据库解耦,只读Redis,由专门的job应用主动填充缓存。

三、缓存穿透

访问一个缓存和数据库都不存在的key,此时会直接打到数据库上,并且因为查不到数据,也不会写入缓存,所以下一次同样会打到数据库上,请求每次都会走到数据库,流量大时可能导致数据库被打挂。

解决方案:
【1】空值缓存: 查询数据库发现没有数据,给对应的key存入一个空值缓存,代表数据库中没有数据,应用查询到空值就直接返回,避免了穿透到DB的读流量。
【2】布隆过滤器:
    1、空值缓存已经能解决问题,但是在数据量非常大的情况下,我们还得考虑空间利用的高效。
    2、布隆过滤器是这样一个数据结构,它有一个初始值为0bit数组以及Nhash函数构成,它可以快速判断或标记当前值是否存在,标记的主要步骤为三个:
         ☑️ 使用Nhash函数计算的Nhash值。
         ☑️ Nhash值与bit数组取模得到N个映射的下标。
         ☑️ 将bit数组中N个下标对应的位置置为1
    3、当我们需要查询一个值时,重复上述步骤1,2得到N个下标,当这N个下标上对应的值均为1,则说明该值已被标记,否则未被标记。
    4、当然由于存在hash冲突,会存在一定的误判,所以布隆过滤器的特点是判断不存在的,则一定不存在;判断存在的,大概率存在。以存在误判的代价,换取空间利用上的高效。
【3】非法值校验: 对于一些请求参数,我们是能够判断出是否合法,如果不合法直接在入口处拦截,自然不需要穿透到DB。比如机票查询请求了一个不存在的航线,我们可以在入口校验时将该请求拦截。

四、缓存击穿

存在一个高并发读的热点key,在缓存过期的一瞬间,有大量的读请求,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,可能导致数据库被打挂。

解决方案:
【1】锁:
    1、当大量请求并发读取缓存并失败时,其实只需要一个线程/机器去访问数据库并填充缓存,其他线程/机器只需等待缓存填充完成后读取缓存就行。
    2、我们可以通过互斥锁使得只有一个线程/机器能够访问数据库并填充缓存,线程间的同步比较容易,因为是在一个进程内,使用java提供的同步机制,比如ReentrantLock即可。
    3、机器间的同步,由于涉及到分布式环境,因此需要分布式锁来进行同步。简单的分布式锁可以通过Redis或者DB实现,更高级的可以通过zookeeper这样的分布式协调服务来实现。

【2】热点数据不过期: 既然缓存击穿是由热点key过期导致的,那么我们可以不为热点数据设置过期时间,而是由专门的后台job应用进行定时的刷新,在携程内部qshcedule能很好的解决我们的需求。


原文地址:https://blog.csdn.net/zhengzhaoyang122/article/details/142864927

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!