排查 Redis 集群 slot 分配不均导致节点负载过高,首选 redis-cli `--cluster` info 查看槽位与键数分布,结合 INFO memory 和 INFO commandstats 确认真实负载,若槽位偏差大则通过 redis-cli `--cluster` reshard 迁移槽位,但需注意槽位均匀不等于负载均匀,热点 Key 和大 Key 才是常见瓶颈。
先说结论:Slot 分配不均会导致数据倾斜,但 CPU 和内存负载过高往往由热点 Key 或大 Key 引起,单纯迁移槽位无法完全解决请求倾斜。
- 先定位:用
redis-cli `--cluster` info对比各节点 slots 和 keys 数量,偏差超过 10% 即视为不均。 - 先做:对高负载节点执行
INFO memory和SLOWLOG GET 5,确认是否因大 Key 或慢命令导致。 - 再验证:迁移槽位后检查客户端是否收到
MOVED响应并刷新拓扑,避免请求仍打向旧节点。
命令速用版
以下命令可直接在运维终端执行,用于快速判断槽位分布与节点负载:
redis-cli `--cluster` info 192.168.10.5:6379:查看集群各节点槽位数量、键数估算和从节点数,识别槽位分配是否均匀。
redis-cli -h <ip> -p <port> INFO memory | grep -E "(used_memory_rss|maxmemory)":单独连接节点查看真实内存占用,used_memory_rss 逼近 maxmemory 说明内存压力大。
redis-cli -h <ip> -p <port> INFO commandstats:查看 cmdstat_get 等命令调用次数,若某节点 calls 值超其他节点 3 倍即判定 QPS 倾斜。
redis-cli `--cluster` reshard 192.168.1.101:7001:交互式迁移槽位,需指定目标节点 ID、迁移数量和源节点。
为什么会这样
Redis Cluster 使用 CRC16 算法计算键的哈希值并对 16384 取模确定槽位,理论上槽位均匀分布即可平衡负载,但业务场景常打破这一假设。
若业务使用了哈希标签(如 user:{1001}:profile),所有含相同标签的键都会落到同一个槽位,导致该槽位所在节点承载远超平均的读写请求。此外,大 Key(如包含 10 万 field 的 hash)在 DBSIZE 中仅计为 1,但实际消耗大量内存和 CPU,导致 redis-cli `--cluster` info 显示的键数分布看似均匀,实际负载却严重倾斜。
分步处理
第一步:检查槽位与键数分布
执行 redis-cli `--cluster` info <ip>:<port>,输出形如 192.168.10.5:6379 -> 1287 keys | 5461 slots。若某节点 slots 为 0 但出现在输出里,说明元数据未清理;若 keys 明显偏高但 slots 一致,说明存在数据倾斜。
第二步:确认真实负载指标
仅靠槽位数量无法反映 CPU 压力。对每个 Master 节点执行 INFO memory 关注 used_memory_rss/maxmemory 比值,执行 INFO commandstats 对比高频命令调用次数。若某节点内存比值超 80% 或 QPS 超其他节点 3 倍,需优先处理热点而非单纯迁移槽位。
第三步:执行槽位迁移
若确认槽位分配不均(如节点间槽数差超过 2%),使用 redis-cli `--cluster` reshard。交互时第一问填迁移槽数量(如 600),第二问填接收节点 ID,第三问填源节点 ID(填 all 表示从所有主节点等比例抽槽)。
第四步:刷新客户端拓扑
迁移完成后,客户端需感知新路由。Lettuce 等客户端需开启 adaptive.refresh=true 并设置 refresh.period=30s,否则旧连接可能持续向旧节点发请求,导致 CPU 压力未转移。
怎么验证是否生效
迁移后再次执行 redis-cli `--cluster` info,确认各节点 slots 数量差值缩小至允许范围内(如 threshold 1.5%)。登录各节点执行 INFO memory,观察 used_memory_rss 是否趋于一致。在客户端日志搜索 Refreshing cluster topology,确认拓扑刷新时间戳间隔符合配置。
若业务侧监控显示原高负载节点 QPS 下降且目标节点 QPS 上升,说明流量已切换。注意观察是否有 MOVED 错误日志,少量 MOVED 属正常重定向,持续大量报错说明客户端未适配新拓扑。
常见坑
rebalance 显示无需均衡但 CPU 仍高:redis-cli `--cluster` rebalance 仅按槽数量判断,不考虑 Key 访问频次。若槽数均匀但负载不均,需手动 reshard 或优化热点 Key。
迁移期间阻塞源节点:migrate 命令会阻塞源节点,单次迁移 slot 数建议≤50,避免超时。大 Key(>1MB)务必提前拆分,否则迁移失败且不报错。
客户端缓存未刷新:迁移完成前已建立连接的旧连接不会自动刷新映射,需等待连接池自然轮换。若用 redis-cli -c 测试能生效但业务代码无效,检查客户端是否复用连接且未处理 MOVED 响应。
常见问题
槽位数量均匀是否代表负载均匀?
不代表。槽位均匀仅说明数据分片逻辑均匀,若存在热点 Key 或大 Key 集中在某槽位,该节点 CPU 和内存负载仍会过高。
reshard 迁移后为什么客户端还在打老节点?
客户端未收到或未处理 MOVED 重定向。现代客户端如 Lettuce、Redisson 会自动更新,但需确保拓扑刷新配置生效,旧连接需等待轮换。
什么场景该用 rebalance 而不是 reshard?
rebalance 适合整体偏斜但无明确目标节点的场景,自动计算迁移;reshard 适合精准补槽、扩容加节点或缩容清空某节点,需人工指定源和目标。
参考来源
- 如何通过命令行查看 Redis 集群各节点的负载情况_执行 redis-cli `--cluster` info 分析资源占比
- 为什么 Redis 集群各节点 QPS 不均衡_检查数据分布倾斜与热点 Key 访问频率
- Redis 集群节点负载不均怎么调_通过移动槽位平衡各节点的 CPU 压力
- 如何解决 Redis Cluster 集群模式下槽位分布不均_利用 reshard 指令重新分配 16384 个槽位
- Redis Cluster 节点流量不均衡问题指南