Redis中的缓存雪崩、缓存击穿和缓存穿透是常见的缓存问题,以下是具体介绍及解决方案:
缓存雪崩
定义:当大量缓存key因过期时间设置相同,在同一时刻集体失效,导致所有请求直接涌向数据库,可能引发数据库崩溃。常见于批量数据缓存场景(如定时任务生成的推荐结果)。
预防措施:
- 随机化过期时间:在批量设置缓存时,为每个key的过期时间添加随机值(如10分钟内随机),避免集中失效。
- 限流保护:若雪崩已发生,可通过限流控制到达数据库的请求量。例如设置每秒查询某key的请求数上限,或采用分布式限流(如Redis+Lua实现)。
应急处理: - 若数据库负载可控,可暂时承受压力;若流量过大,需结合限流或熔断机制(如拒绝部分请求)保护数据库。
缓存击穿
定义:单个热点key因过期或被淘汰,导致大量请求直接穿透缓存访问数据库,可能引发数据库崩溃。常见于秒杀、促销等高并发场景。
解决方案:
- 限流:限制单个key的并发请求数,仅允许少量请求访问数据库,其余请求等待或返回空值。
- 分布式锁:通过Redis实现分布式锁,确保同一时间仅一个线程访问数据库。获取锁的线程负责更新缓存,其他线程等待或重试。
- 热点key预热:通过定时任务或延迟队列监控热点key的过期时间,提前延长其有效期,避免失效。
- 永不失效:对核心热点key设置永久有效(需权衡内存占用与业务需求)。
缓存穿透
定义:请求的key在缓存和数据库中均不存在,导致每次请求都直接访问数据库,可能被恶意利用(如构造大量不存在的key发起攻击)。
解决方案:
- 缓存空值:对不存在的key在缓存中设置空值或特殊标记,并设置较短过期时间,减少重复查询。
- 布隆过滤器:通过位数组和哈希函数快速判断key是否存在。初始化时将数据库所有有效key存入布隆过滤器,请求时先过滤无效key,避免无效数据库查询。
总结:
- 缓存雪崩需通过随机化过期时间和限流预防;
- 缓存击穿需结合限流、分布式锁或热点key预热解决;
- 缓存穿透可通过缓存空值或布隆过滤器拦截无效请求。
实际场景中需根据业务特点选择合适方案,并考虑分布式环境下的扩展性(如分布式锁、限流的实现方式)。