一 概述
在 service 中如果要查询数据,则会到缓存中查询,如果缓存未命中,再到数据库中查询数据。
作为缓存的 Redis 扛住了系统中大量的请求,极大的减小了数据库的压力。
但是当流量很大、高并发时,倘若 Redis 没能扛住,便会导致缓存穿透、缓存击穿、缓存雪崩
二 解决思路
缓存雪崩
原因:大量缓存同时失效或者缓存服务器宕机,导致大量查询直接打到数据库上,造成数据库压力剧增。
解决方法:
给不同的Key设置不同的过期时间,分散缓存失效时间。
实现缓存数据的高可用性,通过设置缓存备份,或者使用集群方式存储缓存数据。
使用锁或队列控制缓存失效后的数据库访问。
实现监控机制,一旦检测到缓存服务器宕机,及时恢复或更新缓存。
缓存击穿
原因:单个Key的缓存由于过期时间太短,导致一个时间点大量请求直接打到数据库上。
解决方法:
设置热点数据永不过期或过期时间长。
使用分布式锁或者互斥锁,控制同时只有一个线程去数据库查询数据并更新缓存。
实现服务限流,当访问量突然增大时,先拒绝部分请求,缓解数据库压力。
缓存穿透
原因:查询不存在的Key,缓存和数据库都不会命中,导致大量请求穿透到数据库上。
解决方法:
实现缓存数据的布隆过滤器,可以预先记录所有可能查询的Key,不存在的Key直接被过滤器拦截。
为缓存设置一个默认值或者一个空值,避免缓存未命中时返回null造成问题。
使用锁或队列控制缓存失效后的数据库访问。
对于非法或者恶意的请求,实现IP黑名单或者参数校验机制,避免请求穿透。
2.1 为什么不建议使用布隆过滤器解决缓存击穿问题?
误报问题:布隆过滤器的误报特性意味着它可能会错误地认为一个不在缓存中的数据项存在于缓存中。如果这个数据项实际上并不存在,那么误报会导致不必要的缓存查找,反而增加了系统负担。
缓存更新问题:布隆过滤器不能用于存储具体的值,只能用于标记存在性。因此,它不能替代缓存来存储实际的数据。
缓存重建问题:缓存击穿问题的核心在于缓存重建时如何避免大量并发请求直接打到数据库。布隆过滤器无法解决这个问题,因为它并不涉及缓存重建的逻辑。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.youkuaiyun.com/weixin_43551213/article/details/141894567
文章2:https://cloud.tencent.com/developer/article/2407203
文章3:https://blog.youkuaiyun.com/fcvtb/article/details/89478554