本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
数据库内大量热点key失效(指定时间同时失效)
访问量增大导致mysql负载过大,宕机了
发生缓存雪崩
场景:京东官网内容,整体图片更换时,需要将Redis内缓存的旧内容清理掉,设置相同时间清理,而就在清理的时候,京东官网有秒杀活动,大量请求,由于Redis内没有缓存需要到MySQL中查找,大量请求MySQL,导致MySQL宕机,称之为缓存雪崩
解决方案:
不同时设计Redis缓存内容过期,伪代码setPassTime(key,value,time)
在时间后面加一个随机数setPassTime(key,value,time+random.nextInt(47))
然后就在同一时间缓存失效较少(就算查询数据库数据库访问压力也不会过大),由此可以防止缓存雪崩
还可以通过
1.保持缓存层的高可用性
使用Redis 哨兵模式或者Redis 集群部署方式,即便个别Redis 节点下线,整个缓存层依然可以使用。除此之外,还可以在多个机房部署 Redis,这样即便是机房死机,依然可以实现缓存层的高可用。
2.限流降级组件
无论是缓存层还是存储层都会有出错的概率,可以将它们视为资源。作为并发量较大的分布式系统,假如有一个资源不可用,可能会造成所有线程在获取这个资源时异常,造成整个系统不可用。降级在高并发系统中是非常正常的,比如推荐服务中,如果个性化推荐服务不可用,可以降级补充热点数据,不至于造成整个推荐服务不可用。常见的限流降级组件如 Hystrix、SenTInel 等。
3.缓存不过期
Redis 中保存的 key 永不失效,这样就不会出现大量缓存同时失效的问题,但是随之而来的就是Redis 需要更多的存储空间。
4.优化缓存过期时间
设计缓存时,为每一个 key 选择合适的过期时间,避免大量的 key 在同一时刻同时失效,造成缓存雪崩。