雪崩
首页等热点信息流数据,更新缓存策略一般有两种
- 用定时任务刷新缓存的策略,每12小时运行一次
- 先从redis查,查不到数据后从mysql查
这种情况下,比如缓存时间设定为12小时,中午12点定时任务刷新过缓存。刚好晚上0点有个秒杀活动大量用户涌入,这些用户从redis取不到数据。所有流量全都打到了mysql,数据库扛不住就会被大流量打死。这个时候重启数据库还是会被瞬间打死,系统的设计本身就不应该允许这么大的并发流量打到mysql上。
解决方案:
- 定时任务刷新redis数据时,在原有过期时间基础上增加随机值。这样可以保证这批key不会同一时间失效
- 热点数据不设置过期时间,数据有更新时去主动更新缓存
- 提高更新缓存定时任务运行频率,保证在大批量数据失效之前去更新数据
穿透
缓存穿透是指缓存和数据库中都没有的数据,不断被用户访问。会导致redis变为摆设,流量同样直接进入mysql。
比如访问id<0的数据,或者已经被删除、逻辑上不允许访问的数据。
解决方案:
- 参数校验,非法参数在进入业务函数之前就应该被拦截
- 不存在的数据也保存到redis,标记为空数据。也可以用redis本身提供的Bloom Filter来实现检查数据是否存在
击穿
一个热点key,不停的扛着大并发。在这个key失效的瞬间持续的大并发会穿破缓存。直接请求数据库,也会造成数据库负载过高。业务响应时间变长、宕机。
解决方案:
- 设置热点数据永不过期
- 取数据写缓存时加互斥锁
网友评论