Redis雪崩、击穿、穿透
缓存预热
问题:服务器启动之后,迅速宕机。
排查特征:请求数量多,主从之间数据吞吐较大,数据同步操作频繁。
缓存预热就是系统启动之前,提前将相关的缓存数据直接加载到缓存系统,避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题。用户直接查询实现被缓存的缓存数据。
方案
前期准备
- 日常例行统计数据访问记录,统计访问频度较高的热点数据。
- 利用LRU数据删除策略,构建数据存留队列。
准备工作
- 将统计结果中的数据分类,根据级别,Redis优先加载级别较高的热点数据
- 利用分布式多服务器进行数据读区,提供数据加载过程
实施
- 使用脚步程序固定出发预热过程
- 如果条件允许,使用CDN(内容分发网络),效果会更好
缓存雪崩
问题:
- 系统平稳运行过程中,忽然数据库连接激增
- 应用服务器无法及时处理请求
- 大量的408、500错误页面出现
- 客户反复刷新页面获取数据
- 数据库崩溃
- 应用服务器崩溃
- 重启应用服务器无效
- Redis服务器崩溃
- Redis集群崩溃
- 重启数据库之后再次被瞬间流量放倒
短时间内,大量的缓存中key集中过期。导致短周期内redis大量未命中,向数据库请求数据,数据库无法同时处理大量的请求,导致Redis请求被积压并开始出现超时。此时重启并不能解决缓存中没有数据的问题。同时,数据库流量激增,导致数据库崩溃;Redis大量任务积压,资源被严重占用,Redis崩溃;应用服务器无法及时得到响应数据,来自客户的请求激增,应用服务器崩溃。
解决
导致此问题的原因就是短时间内,大量的缓存中key集中过期。所以解决方案可以有以下:
道(思想、原则)
- 更多的页面静态化处理,尽可能的降低从缓存中取数据的次数
- 构建多级缓存:Nginx缓存+redis缓存+ehchche缓存
- 检测数据库中严重耗时的相关业务,并进行优化
- 限流、降级:短时间牺牲部分用户的体验,限制一部分的请求访问,降低应用服务器压力,待业务稳定之后逐步放开
术(方式、方法)
- LRU(到期删除)于LFU(按命中次数删除)切换
- 数据有效期策略:对业务数据进行分类错峰,比如不同类的缓存数据舍得不同长度的过期时间。在同一个类里,过期时间设定为固定时间+随机值的形式,减少集中过期的发生
- 超热的数据使用永久key
总结
雪崩就是瞬间过期的数据量太大,导致数据库服务器压力激增。如果能有效避免数据集中过期,可以有效避免雪崩的现象。
缓存击穿
问题:Redis中某个key过期,该key的访问量巨大。多个数据请求来到Redis之后,未命中。Redis就会在短时间大量访问数据库中的同一数据。
该问题的原因是,单个key高热,且过期。
解决
术
- 预先设定:比如电商平台上的促销商品
- 现场调整:监控访问量,对自然流量激增的数据延长过期时间
- 刷新数据:启动定时任务,高峰来临之前,属性数据有效期,确保不丢失
- 二级缓存:设置不同的有效时间,保证相关的key不被同时过期
- 加锁:分布式锁,防止被击穿,但是要注意锁的性能瓶颈
总结
缓存击穿就是单个高热数据过期的瞬间,数据量访问较大,未命中Redis,对数据库的同一数据发起大量访问,导致数据库服务器压力增大。
缓存穿透
问题:Redis中大面积出现为命中,出现非正常的URL。
数据库中不存在该数据,Redis获取的null也未进行缓存持久化,直接返回。下次类似的请求重复上述过程。黑客采用此方式进行攻击。
解决方案
术
- 对查询结果为null对数据进行缓存,设置短期的过期时间(几十秒。临时的应对策略)。
- 白名单策略:提前预热各种分类数据对应的ID(可使用bitmaps)。加载正常数据的时候,放行。加载异常数据的时候直接拦截(效率偏低)
- 实施监控:对Redis的命中率进行监控,如果命中率和null比较,超过平时正常业务范围的几十倍,那么启动相应的排出流程,可加入黑名单