Redis缓存穿透/缓存雪崩/缓存击穿(案例:产生的原因 解决方案利/弊)
缓存穿透
缓存穿透:去缓存查询没有命中数据 而进mysql查询数据
不能避免低频缓存穿透,避免高频的缓存穿透
第一种
id=-1
黑客通过一个固定非法请求去攻击数据库
可采用null再次缓存的解决方案
第二种
id=uuid
过滤器
在redis和mysql之间安装一个过滤器
(1) 解决过滤器内存紧张的问题
布隆算法 :通过一定的错误率换取空间
通过一个bit数组来标识
1 hash的范围[0,length-1]
2 计算出来hash值 足够散列
3 数组初始化全是0
4 比如id=10 计算出hash值=5 那么标识bit数组下标等于5的标记为1
5 存在hash碰撞
6 减少hash配置 多用几个hash函数 同时标记
7 弊端删除数据 (bit数据里的值1 不能随便改成0)
解决方案 : 搞一个计数器二位数组 如果计数器为可以删除
hash 错误率
布隆算法说数据存在,那么实际可能不存在(hash碰撞)
说数据不存在,那么肯定不存在
缓存雪崩
缓存层在 在某一个时刻(无法访问)导致大量的请求大向mysql数据库
可能发生缓存雪崩的原因
(1) redis中缓存的数据有效期一致
解决方案: 对不同的数据设置不同的有效期(随机有效期)
(2) redis数据库挂掉了
解决方案:分布式缓存
分布式缓存
传统的算法 hash取模 数据相对平均
缺点 : 不利于集群扩展
redis集群的hash一致性算法(解决集群的扩展)
hash一致性也有弊端 数据倾斜
增加虚拟节点 (redis槽 16384)
缓存击穿(一般公司不解决)
缓存击穿 : redis只缓存一条数据
解决方案分布式锁
弊端: 会出死锁
解决方案: 监听锁的时间 超出设置的timeout 干掉锁
新的问题: timeout设置多长 ???
1s 很短 发生了GC挂了 下一个进程抢到了 (2个进程打架)
10s
1年(哈哈) 下一个进程等待1年-1s
zookeeper实现分布式锁 临时有序的节点
其实并不需要这么繁琐 : mysql 查来放进redis缓存就 OK 了
总结 缓存击穿和缓存雪崩本身都是缓存穿透
缓存击穿和缓存雪崩是缓存穿透的特殊表现
本作品采用《CC 协议》,转载必须注明作者和本文链接