如何解决Redis的缓存雪崩、缓存击穿、缓存穿透?
在redis的使用中特别是有大体量业务的场景,Redis的这三大缓存问题是比较常见的。这篇文章来分析一下, 这三个问题到底是什么,以及有什么解决方案。
1、缓存雪崩
缓存雪崩
的发生主要有两个场景,一个是有大量的请求无法再Redis缓存中处理,从而将这大量的请求,发送到数据库层,导致数据库的压力激增,从而影响其他业务的正常运行。另一个是Redis实例宕机,导致大量请求无法访问Redis实例,从而将大量请求发送到数据库层。
解决方案①: 避免让大量的key在同一时间内过期,就算有同时过期的需求,那可以每个过期时间随机加1-3分钟。这样key的过期时间相差不大,也符合业务逻辑的同时,减少了大量请求访问数据库的场景。
解决方案②: 设计服务熔断机制。通过检测Redis实例与数据库的负载指标,判断Redis实例是否崩溃并且数据库的每秒请求量激增,如果出现这种情况,大概率就是发生缓存雪崩了,这样就可以开启服务熔断机制,避免因为缓存雪崩造成数据库雪崩甚至系统崩溃的连锁反应。
解决方案③: 增加Redis集群,但是要注意Redis的一致性hash环集群,避免当一个主从节点崩溃后,大量请求就会分散到其他的主从节点,导致直接将所有的节点都冲垮了。
2、缓存击穿
缓存击穿
主要针对的是热点数据,当有大量热点数据的请求访问redis,但是这些热点数据的key都过期了,这时候又会有大量的请求到数据库,导致数据库的压力激增。
解决方案①:不要为热点数据设置过期时间,但是要做好更新缓存的方案,比如定时任务
解决方案②:可以在读热点数据的时候再次判断热点数据的热度,如果热度高,可以推迟这个热点数据的过期时间。
解决方案③:增加互斥锁,当热点数据的key失效后,仅一个允许一个线程重建缓存,其他线程等待或返回空值。
补充说明:还可以利用Redis的hotkeys命令或监控工具主动识别热点key,并提前预热。
3、缓存穿透
缓存穿透
是指有大量请求在redis缓存中与数据库中都找不到数据,导致缓存层与数据库层的压力都很大,这也让Redis缓存层形同虚设。这个问题的发生原因主要是因为被人用不存在的数据恶意攻击了。
解决方案①:为相关的服务做服务降级/熔断/限流等操作,但是这属于事后弥补,属于“有损”的方案,因为实际的影响已经造成了。所以不建议使用。
解决方案②:增加布隆过滤器,在缓存层之前设计,用于快速的判断数据是否存在。
解决方案③:当有一次请求异常的情况发生,就在Redis中缓存一个空值或缺省值并设计较短的过期时间。这样,当又有相同的请求访问,就会直接返回缺省值的数据。
解决方案③:在前端对异常请求进行限制,把这个问题直接拦截掉。