前言
之前在针对实习面试的博文中讲到Redis在实际开发中的生产问题,其中缓存穿透、击穿、雪崩在面试中问的最频繁,本文加了图解,希望帮助你更直观的了解缓存雪崩😀
(放出之前写的针对实习面试的关于Redis生产问题的博文链接)
Redis生产问题(缓存穿透、击穿、雪崩)------针对实习面试
什么是缓存雪崩?
缓存雪崩是指:在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。这种场景就像雪崩一样,所以叫缓存雪崩
缓存雪崩可能由以下几个原因引起:
-
缓存数据集中过期:如果缓存数据的过期时间设置不合理,比如很多缓存数据设置为在同一时间过期,那么在过期时刻,缓存将无法提供数据,导致请求直接落到数据库上。
-
缓存服务不可用:如果缓存服务由于某些原因(如宕机、网络问题等)变得不可用,那么所有的请求都会直接访问数据库。
-
数据库压力过大:当大量的请求直接访问数据库时,如果数据库没有足够的能力处理这些请求,可能会导致数据库响应缓慢甚至崩溃。
怎么解决缓存雪崩
解决缓存雪崩的最常用措施包括:
1. 过期时间随机化
为了避免大量缓存数据在同一时间过期,可以给缓存数据的过期时间加上一个随机值。这样,即使有大量数据需要设置为过期,它们也不会在同一时刻全部失效,从而减少了对数据库的瞬间压力。
图表:
+----------------+ +--------+ +------------+
| | 过期 | | 请求 | |
| 用户请求数据 +-------->+ 缓存 +-------->+ 数据库 |
| | | | | |
+----------------+ +--------+ +------------+
在缓存设置中加入随机过期时间,可以避免大量缓存数据在同一时间过期,从而减少数据库的压力 。
2. 搭建Redis高可用集群
通过搭建Redis高可用集群,可以有效地防止缓存雪崩问题的发生。如果主节点发生故障,从节点可以接管服务,继续提供缓存服务,避免了由于单点故障导致的缓存雪崩问题。
图表:
+--------+ +--------+
| | | |
| Redis +------->+ Redis |
| Master| | Slave |
| | | |
+--------+ +--------+
通过Redis的主从复制、双主、读写分离等策略,提高数据库的容灾能力 。
3. 限流和降级策略
在缓存雪崩时,可以采取限流、降级等策略,减缓数据库的压力。例如,在缓存失效后,通过加锁或者使用队列来控制读数据库写缓存的线程数量。具体点就是设置某些Key只允许一个线程查询数据和写缓存,其他线程等待。则能够有效的缓解大并发流量对数据库打来的巨大冲击 。
4. 数据预热
在系统上线前,提前将热点数据加载到缓存中,避免大量请求同时触发缓存未命中的情况 。
如何实现:
- 使用定时任务,比如 xxl-job,来定时触发缓存预热的逻辑,将数据库中的热点数据查询出来并存入缓存中。
- 使用消息队列,比如 Kafka,来异步地进行缓存预热,将数据库中的热点数据的主键或者 ID 发送到消息队列中,然后由缓存服务消费消息队列中的数据,根据主键或者 ID 查询数据库并更新缓存
5. 多级缓存架构
使用本地缓存(如 Caffeine、Guava 等)和分布式缓存(如 Redis)相结合的方式,部分热点数据可以先放入本地缓存,降低 Redis 和数据库的压力 。
6. Redis 高可用
部署 Redis 主从集群,使用 Redis 的哨兵模式(Sentinel)或者 Redis Cluster 来实现高可用,避免缓存服务器单点故障 。