推荐答案
1. 设置缓存过期时间的随机值
为了避免大量缓存同时失效,可以为每个缓存项设置一个随机的过期时间。例如,在基础过期时间上增加一个随机的时间偏移量。
import random import time def set_cache_with_random_expiry(key, value, base_expiry, max_random_offset): expiry = base_expiry + random.randint(0, max_random_offset) redis_client.set(key, value, ex=expiry)
2. 使用多级缓存
引入多级缓存机制,如本地缓存(如Guava Cache)与Redis缓存结合使用。当Redis缓存失效时,可以先从本地缓存中获取数据,减少对数据库的直接压力。
3. 缓存预热
在系统启动或低峰期,提前加载热点数据到缓存中,避免在高峰期缓存失效时大量请求直接打到数据库。
4. 限流与降级
在缓存失效时,通过限流和降级策略来控制请求的流量,避免数据库被大量请求压垮。可以使用Hystrix等工具来实现限流和降级。
5. 使用分布式锁
在缓存失效时,使用分布式锁(如Redis的SETNX
命令)来确保只有一个请求去数据库加载数据,其他请求等待缓存更新。
-- -------------------- ---- ------- --- ------------------------ ----- - --------------------- -- ----- -- ----- -------- - ------------- -- ---------------------------- --- ----------------------------- --- - -------- - -------- ----- - ---------------------- --------------------- ------ -------- - ---- ----------------------------- ----- - ----- --------------- ------ ----------------------- ------ -----
本题详细解读
1. 缓存雪崩的定义
缓存雪崩是指在某一时刻,大量缓存同时失效,导致所有请求都直接打到数据库,造成数据库压力骤增,甚至导致数据库崩溃。
2. 缓存雪崩的原因
- 缓存集中过期:大量缓存在同一时间过期,导致请求直接访问数据库。
- Redis宕机:如果Redis服务宕机,所有缓存失效,请求也会直接打到数据库。
3. 解决方案的核心思想
- 分散缓存过期时间:通过设置随机的过期时间,避免大量缓存同时失效。
- 多级缓存:通过引入多级缓存,减少对单一缓存层的依赖。
- 限流与降级:在缓存失效时,通过限流和降级策略保护数据库。
- 分布式锁:确保只有一个请求去数据库加载数据,避免重复加载。
4. 实际应用中的注意事项
- 随机过期时间的范围:随机偏移量不宜过大,否则可能导致缓存过早失效。
- 多级缓存的同步:确保多级缓存之间的数据一致性。
- 限流与降级的阈值:根据系统的实际负载情况,合理设置限流和降级的阈值。
- 分布式锁的性能:分布式锁的使用可能会引入一定的性能开销,需谨慎使用。