系统学习 故障排查学习路径:从方法论到系统、网络、数据库与 K8s

incident-redis-hotkey

一次促销配置热 Key 打满 Redis Cluster 单分片的复盘(匿名化合成案例)。

现象

某业务集群使用 Redis Cluster 缓存活动配置。活动开始后,部分接口的 p99 延迟从几十毫秒升到数秒,并出现连接超时和重试。Redis 集群总 CPU 看起来只有三成左右,但其中一个主节点的单核 CPU 已接近 100%;同一分片上的其他 key 也开始变慢,其他分片仍然平稳。内存、网络和集群状态没有明显异常。

时间线

影响面

受影响的不只是活动配置接口。哈希槽落在该分片上的其他 key 也共享同一个事件循环,因此一些无关业务出现了延迟升高和超时。客户端重试又放大了流量,形成短时拥塞。没有数据丢失或主从切换,但部分请求在 HTTP 层返回超时,用户侧表现为页面加载慢或重试。

误导线索

第一个误导信号是集群聚合 CPU。整体只有三成,很容易让人认为 Redis 还有大量余量,于是转向排查网络和客户端。真正有意义的指标是每个主节点的 CPU、事件循环延迟和该节点上的命令耗时;一个 Cluster 有多个分片,不代表负载会自动均摊,一个 key 永远只属于一个哈希槽和一个主节点。

第二个误导信号是空的 SLOWLOG。慢日志记录的是命令执行时间,不包含命令在 socket 和事件循环队列里等待的时间。单次 GET 本身很快,但当分片被打满后,请求会先在队列中排队,客户端看到的是整体延迟和超时,慢日志却可能没有任何记录。MEMORY USAGE 也证明这个 key 并不大,推翻了“大 key 导致阻塞”的假设。最后是应用维度和 CLUSTER KEYSLOT 的证据把问题锁定到单一热 key。

根因

活动配置是一个读多写少、访问极度集中的 key。它所在的槽位只能由一个主节点处理,而 Redis 执行命令的主线程是单线程模型,单核被打满后,同一分片上的所有请求都要排队。配置统一过期、应用没有本地缓存和 singleflight,导致大量并发 miss 同时回源并回填;活动流量和客户端重试叠加,最终把一个普通小 key 变成了热点。

这不是“集群容量不足”的平均问题,也不是大 key 或慢命令问题。增加分片数量不会自动拆散一个 key,重新分片也只能迁移整个槽位,仍然只有一个主节点承接该 key 的读写。

修复

先降低放大效应,再处理 key 的分布。确认该配置短暂陈旧可接受后,在应用侧增加带随机抖动的短 TTL 本地缓存,并对同 key 的 miss 做请求合并,避免所有实例同时回源。给客户端设置明确超时、限制重试次数并加入退避和抖动,防止重试风暴继续打满分片。

定位和验证命令如下:

redis-cli --cluster call <host>:<port> INFO cpu
redis-cli --cluster call <host>:<port> INFO commandstats
redis-cli --cluster check <host>:<port>
redis-cli -c -h <host> -p <port> CLUSTER KEYSLOT <key>
redis-cli -c -h <host> -p <port> CLUSTER NODES
redis-cli -c -h <host> -p <port> SLOWLOG GET 20
redis-cli -h <host> -p <port> CONFIG GET maxmemory-policy

只有确认淘汰策略为 LFU 时,才在对应主节点上使用 redis-cli --hotkeys;它会扫描 key,本身也有开销,不要在高负载时反复执行。MONITOR 更不适合直接开在高 QPS 主节点上,必须采样时应在低峰、限时并设置超时,优先使用应用侧埋点和代理日志。

长期修复根据读写性质选择:

预防

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. 为什么集群总 CPU 不高,仍可能出现 Redis 热 key 故障?
  2. 慢日志为空为什么不能排除 Redis 侧延迟?
  3. 增加分片或只读副本能否直接解决单个热 key?
答案
  1. 热 key 只落在一个哈希槽和一个主节点上。集群总 CPU 是各分片的平均或汇总,其他分片空闲时,单分片仍可能把一个主线程打满。必须看每个主节点的 CPU 和延迟。
  2. 慢日志统计命令执行时间,不统计请求在网络和事件循环队列中的等待时间。分片饱和时,单个 GET 仍可能很快执行,但客户端早已在排队和超时。
  3. 不能直接解决。增加分片不会拆分一个 key,整个槽位只会迁移;只读副本只有在客户端支持读路由且能接受复制延迟时才有帮助。根因治理是本地缓存、请求合并、TTL 抖动或按业务拆分 key。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令