1. 面试题
2. 缓存预热
当Redis暂时没有数据,但MySQL中有数据时,由程序员、中间件、写段程序提前访问该数据,使得数据进行回写进Redis,从而达到缓存预热的效果,这样可以使得一开始访问页面程序的用户也没有卡顿(提前将数据写入Redis即缓存预热)
3. 缓存雪崩
发生原因:
- Redis主机挂了,全盘崩溃,偏硬件运维的原因
- Redis中的key大量同时过期(失效),偏软件开发的原因
3.1 解决方案
- 将Redis中的key设置永不过期或者错开key过期失效的时间
- Redis集群实现高可用(主从+哨兵、Redis Cluster、 开启持久化机制(aof/rdb)尽快恢复缓存集群)
- 多缓存结合预防雪崩(ehcache本地缓存+Redis缓存)
- 服务降级(阿里巴巴Sentinel服务限流&降级)
4. 缓存穿透
请求去查询记录时,Redis无数据,MySQL数据库中也没有数据,无法进行回写机制,那么每次有这种请求都会打到MySQL数据库中,造成后台数据库压力暴增,这种现象称为缓存穿透,此时Redis成了摆设
4.1 解决方案
方案一:空对象缓存或者缺省值(短期,暂时的解决方案)
第一种解决方案,回写增强
如果发生了缓存穿透,我们可以针对要查询的数据,在Redis里存一个和业务部门商量后确定的缺省值(比如,零、负数、defaultNull等)。
比如,键uid:abcdxxx,值defaultNull作为案例的key和value
先去redis查键uid:abcdxxx没有,再去mysql查没有获得 ,这就发生了一次穿透现象。
but,可以增强回写机制
mysql也查不到的话也让redis存入刚刚查不到的key并保护mysql。
第一次来查询uid:abcdxxx,redis和mysql都没有,返回null给调用者,但是增强回写后第二次来查uid:abcdxxx,此时redis就有值了。
可以直接从Redis中读取default缺省值返回给业务应用程序,避免了把大量请求发送给mysql处理,打爆mysql。
但是,此方法架不住黑客的恶意攻击,有缺陷......,只能解决key相同的情况
黑客恶意攻击:当key拿个符合规则但数据库又不存在的key进行访问时的解决方案
- key相同的情况下,第一次打到MySQL上,缓存回写第二次访问就会返回defaultNull缺省值,此时可以避免黑客攻击打到后台数据库
- key不相同的情况下,由于空对象缓存回写,Redis中会存在越来越多无关紧要的key(此时需要对key设置过期时间)
方案二:Google布隆过滤器Guava解决缓存穿透(目前主流方案)
误判率越低,所消耗的资源越多(因为要更大的bit空间进行存储数据和更多的哈希函数使得数据分布的更均匀)
5. 缓存击穿
大量请求同时查询同1个key,此时key刚好失效,(热点key失效)导致这些请求打到后台数据库上,该情况称为缓存击穿
该情况会导致某一时刻数据库请求量过大,压力剧增
5.1 解决方案
- 差异化失效时间,对于热点数据直接不设置失效时间
- 互斥更新,双检加锁