Redis-- 缓存预热+缓存雪崩+缓存击穿+缓存穿透**加粗样式**
- 一 面试题引入
- 二 缓存预热
- 三 缓存雪崩
- 3.1 问题现象
- 3.2 预防+解决
- 四 缓存穿透
- 4.1 定义
- 4.2 解决方案
- 4.2.1 空对象缓存或者缺省值
- 4.2.2 Google布隆过滤器Guava解决缓存穿透
- 五 缓存击穿
- 5.1 定义
- 5.2 危害
- 5.3 解决
- 六 总结
一 面试题引入
- 缓存预热、雪崩、穿透、击穿分别是什么?你遇到过哪几种情况?
- 缓存预热你是怎么做的?
- 如何避免或者减少缓存雪崩?
- 穿透和击穿有什么区别?他两是一个意思还是截然不同?
- 穿透和击穿你有什么解决方案?如何避免?
- 假如出现了缓存不一致,你有哪些修补方案?
- …
二 缓存预热
@PostConstruct初始化白名单数据
三 缓存雪崩
3.1 问题现象
- redis主机挂了,Redis全盘崩溃,偏硬件运维。
- redis中有大量key同时过期大面积失效,偏软件开发
3.2 预防+解决
- redis中key设置为永不过期or过期时间错开。
- redis缓存集群实现高可用
- 主从+哨兵。
- Redis Cluster。
- 开启redis持久化机制aof/rdb,尽快恢复缓存集群。
- 多缓存结合预防雪崩:ehcache本地缓存+redis缓存
- 服务降级:Hystrix或者阿里sentinel限流&降级
四 缓存穿透
4.1 定义
请求去查询一条记录,先查redis无,后查mysql无,都查询不到该条记录。但是请求每次都会达到数据库上面去。导致后台数据库压力暴增。这种现象我们称为缓存穿透,这个redis变成了一个摆设。
4.2 解决方案
4.2.1 空对象缓存或者缺省值
回写增强: 如果发生了缓存穿透,我们可以针对要查询的是,在Redis里存一个和业务部门商量后确定的缺省值(比如:零、负数、default、Null等。)比如,键uid:abcdXXX,值defaultNull作为案例的key和value。
先去redis查键uid:abcdxxx没有,再去mysql查没有获得,这就发生了一次穿透现象。
通过增强回写机制,mysql也查不到的话也让redis存入刚刚查不到的key并保护mysql。
但是此方法架不住黑客的恶意攻击,有缺陷...,只能解决key相同的情况。
黑客或者恶意攻击:
黑客会对你的系统进行攻击,拿一个不存在的id去查询数据,会产生大量的请求到数据库区查询,可能会导致你的数据库由于压力过大而宕机。
- key相同:第一次达到mysql,空对象缓存后第二次就返回defaultNull缺省值,避免mysql被攻击,不用再导数据库中去走一圈了。
- key不同:由于存在空对象缓存和缓存回写,redis中的无关紧要的key也会越写越多(记得设置redis过期时间)。
4.2.2 Google布隆过滤器Guava解决缓存穿透
- 让布隆过滤器作为白名单使用:白名单里面有的才让通过,没有直接返回。但是存在误判,由于误判率很小,1%达到mysql,可以接受。注意:所有key都需要往redis和bloomfilter里面放入。
- 误判问题,但是概率小可以接受,不能从布隆过滤器删除元素
- 全部合法的key都需要放入Guava版布隆过滤器+redis里面,不然数据就是返回null。
五 缓存击穿
5.1 定义
大量的请求同时查询一个key时,此时这个key正好失效了,就会导致大量的请求都达到数据库上面去。
简单说就是热点key突然失效了,暴打mysql。
穿透和击穿,截然不同。
5.2 危害
- 会造成某一时刻数据库请求量过大,压力剧增。
- 一般技术部门需要知道
热点key是那些个?
做到心里有数防止击穿。
热点key失效原因: - 时间到了自然清除但还被访问到。
- delete掉的key,刚巧又被访问。
5.3 解决
-
差异失效时间,对于访问频繁的热点key,干脆就不设置过期时间。
-
互斥更新,采用双检加锁策略