Redis缓存异常
在 Redis 缓存使用过程中,会遇到多种异常情况,合理处理这些异常对保障系统稳定性至关重要。以下是常见的 Redis 缓存异常及对应的处理方式:
1. 缓存穿透
- 现象:查询不存在的数据,请求穿透缓存直接打到数据库,可能导致数据库压力骤增。
- 原因:恶意攻击(如查询不存在的 ID)、业务逻辑漏洞等。
- 处理方式:
- 缓存空值:对查询结果为空的数据,也在缓存中存储空值(设置较短过期时间),避免重复穿透。
- 布隆过滤器:预先将存在的 key 存入布隆过滤器,查询前先校验,不存在则直接返回。
2. 缓存击穿
- 现象:热点 key 突然过期,大量请求同时访问该 key,瞬间穿透到数据库。
- 原因:热点数据过期、缓存服务重启等。
- 处理方式:
- 互斥锁:多个请求竞争同一 key 时,只有一个请求能去数据库查询,其他请求等待重试。
- 热点 key 永不过期:核心热点数据不设置过期时间,通过后台异步更新。
- 过期时间错开:对同类热点 key 设置随机过期时间,避免同时失效。
3. 缓存雪崩
- 现象:大量缓存 key 同时过期或 Redis 服务宕机,导致所有请求涌向数据库,可能引发数据库崩溃。
- 原因:缓存集中过期、Redis 集群故障、网络问题等。
- 处理方式:
- 过期时间随机化:给 key 的过期时间增加随机值,避免集中过期。
- 多级缓存:结合本地缓存(如 Caffeine)和分布式缓存,降低 Redis 压力。
- 服务熔断降级:使用 Sentinel、Hystrix 等工具,当 Redis 故障时,快速失败并返回默认值。
- Redis 集群高可用:部署主从、哨兵或集群模式,避免单点故障。
4. 缓存与数据库一致性问题
- 现象:缓存数据与数据库数据不一致,导致业务逻辑错误。
- 原因:更新数据库后未同步更新缓存、并发读写导致的数据覆盖等。
- 处理方式:
- 先更新数据库,再删除缓存(Cache Aside Pattern)。
- 延迟双删:更新数据库后删除缓存,间隔一段时间再次删除(应对并发场景)。
- 写入消息队列:通过 MQ 异步更新缓存,保证最终一致性。
5. Redis 连接异常
- 现象:无法连接 Redis 服务,抛出连接超时、拒绝连接等异常。
- 原因:Redis 服务宕机、网络故障、连接池参数不合理等。
- 处理方式:
- 连接池配置:合理设置最大连接数、超时时间、重试机制。
- 异常捕获与重试:捕获连接异常,使用指数退避策略进行有限次重试。
- 健康检查:定期检测 Redis 服务状态,故障时切换到备用节点。
6. 内存溢出(OOM)
- 现象:Redis 内存达到 maxmemory 限制,无法写入新数据。
- 原因:内存配置不足、缓存数据未及时清理、内存碎片过多。
- 处理方式:
- 合理设置 maxmemory 和淘汰策略(如 LRU、LFU)。
- 定期清理无效数据,优化过期策略。
- 监控内存使用,及时扩容或拆分数据。
7. 大 key 与热 key 问题
- 现象:大 key 导致网络拥塞、内存占用过高;热 key 导致 Redis 节点负载不均。
- 处理方式:
- 大 key 拆分:将大型集合拆分为多个小 key。
- 热 key 分散:通过添加前缀哈希将热 key 分散到不同节点。
- 本地缓存:将热 key 加载到应用本地缓存,减少 Redis 访问。
处理缓存异常时,需结合业务场景选择合适方案,同时加强监控告警(如 Redis 内存、连接数、命中率等指标),提前发现并解决潜在问题。