前言

Redis 故障经常不是 Redis 挂了,而是访问模式不合理。热 Key、大 Key、缓存击穿、缓存雪崩都会把缓存层和数据库层一起拖慢。面试时要能把缓存问题和业务场景结合起来讲。

典型现象

  • Redis CPU 飙高。
  • 某个接口 RT 突然变长。
  • 数据库 QPS 突然上升。
  • Redis 慢查询增加。
  • 应用 Redis 连接池耗尽。
  • 集群中某个分片负载明显高于其他分片。

排查流程

flowchart TD
    A[接口变慢或DB压力升高] --> B[查看缓存命中率]
    B --> C{命中率是否下降}
    C -->|是| D[排查穿透/击穿/雪崩]
    C -->|否| E[排查热Key/大Key/慢查询]
    D --> F[限流/互斥/空值缓存]
    E --> G[拆Key/本地缓存/数据结构优化]
    F --> H[长期治理]
    G --> H

热 Key

热 Key 是大量请求集中访问同一个 Key,比如秒杀商品库存、首页配置、热门商品详情。

排查方式:

  • 查看 Redis 节点 CPU。
  • 看应用访问日志中的 Key 分布。
  • 使用 Redis 集群节点指标判断分片倾斜。
  • 结合业务活动时间点分析。

处理方式:

  • 本地缓存。
  • 多副本 Key。
  • 热点数据预热。
  • 请求限流。
  • 将热点读请求和普通读请求隔离。

大 Key

大 Key 是 value 很大或集合元素很多的 Key。

危害:

  • 网络传输慢。
  • 序列化和反序列化耗时。
  • 删除阻塞。
  • 主从同步压力大。
  • 集群迁移慢。

排查方式:

1
2
redis-cli --bigkeys
redis-cli slowlog get

处理方式:

  • 拆分 Key。
  • 集合分页读取。
  • 使用 unlink 异步删除。
  • 控制单个 value 大小。
  • 大对象不要直接塞 Redis。

缓存穿透

穿透是请求的数据不存在,缓存和数据库都没有,导致每次都打到数据库。

常见原因:

  • 恶意请求不存在 ID。
  • 商品被删除后仍有大量访问。
  • 参数校验不严格。

解决方式:

  • 空值缓存。
  • 布隆过滤器。
  • 参数合法性校验。
  • 网关限流和黑名单。

缓存击穿

击穿是热点 Key 过期,大量请求同时打到数据库。

解决方式:

  • 互斥锁重建缓存。
  • 逻辑过期。
  • 热点 Key 不设置短 TTL。
  • 后台异步刷新。

逻辑过期适合读多写少、允许短时间旧数据的场景。互斥锁适合一致性要求更高的场景,但要控制锁等待时间。

缓存雪崩

雪崩是大量 Key 同时失效,或者 Redis 整体不可用,导致请求集中打到数据库。

解决方式:

  • TTL 增加随机值。
  • 缓存预热。
  • 多级缓存。
  • Redis 高可用。
  • 降级和限流。
  • 数据库保护开关。

连接池耗尽

应用侧 Redis 连接池耗尽常见原因:

  • Redis 慢查询。
  • 大 Key 读写。
  • 网络抖动。
  • 连接池配置过小。
  • 同步调用太多。

排查时要看连接获取耗时、active 连接数、Redis 命令耗时和接口调用次数。

生产止血

  • 对热点接口限流。
  • 打开本地缓存或降级缓存。
  • 临时延长热点 Key 过期时间。
  • 暂停异常批量删除任务。
  • 对不存在参数做网关拦截。
  • 必要时保护数据库,只保留核心请求。

高频面试题

热 Key 怎么解决?

先确认热点 Key 和访问来源,再通过本地缓存、多副本 Key、热点预热、限流和读写隔离缓解。核心是不要让所有请求都集中到一个 Redis 分片。

大 Key 有什么危害?

大 Key 会增加网络传输、序列化、删除阻塞、主从同步和集群迁移成本,还可能拖慢单线程 Redis。

击穿和雪崩有什么区别?

击穿是单个热点 Key 失效导致大量请求打 DB,雪崩是大量 Key 同时失效或缓存整体不可用导致 DB 被打爆。

总结

Redis 故障排查要从命中率、Key 分布、命令耗时、连接池和数据库压力一起看。缓存层的问题往往会连带影响应用和数据库。