集群客户端与路由
集群客户端与单机客户端的本质差别在路由:客户端持有一份「槽到节点」的映射表,请求发到不负责该槽的节点时,要么跟随 MOVED 永久重定向更新映射,要么在槽迁移期间按 ASK 临时改道。拓扑变化(扩容、迁移、故障切换)后映射表还要能刷新,否则会出现服务端一切正常而应用持续报错的假象。redis-cli 加 -c 就是打开这种跟随模式,是排查集群问题时最常用的一把工具。
基本信息
| 调试入口 | redis-cli -c -p <端口>,不加 -c 不会跟随重定向 |
|---|---|
| 种子节点 | 配置里只填少量种子地址,其余拓扑通过 CLUSTER SLOTS 自动发现 |
| 必须处理 | MOVED 永久重定向、ASK 迁移中的临时重定向、CLUSTERDOWN、TRYAGAIN |
| 客户端要求 | 路由表缓存与刷新、按节点维护连接池、失败的有限重试 |
| 从库读取 | READONLY 模式允许从从库读,一致性比主库更弱 |
| 拓扑体检 | redis-cli --cluster check <任意节点> |
典型使用场景
- 排查重定向:分清是客户端路由没刷新,还是服务端槽归属真的异常
- 定位热点键:先查键的槽号与所属节点,再连到该实例上分析大 key 与慢命令
- 扩容后验证:槽迁移结束后确认客户端是否已学到新拓扑,抽查读写是否正常
- 客户端选型评估:确认目标语言的客户端是否支持集群模式、重定向与拓扑刷新
- 读流量分摊:用 READONLY 连接把读请求导向从库,前提是业务能接受复制延迟
调试与定位
调试与定位
redis-cli -c -p 7000 SET user:1 alice # 带 -c,命中错槽会自动跟随 MOVED 重试
redis-cli -p 7000 SET user:1 alice # 不带 -c,直接返回 MOVED 错误
redis-cli -c -p 7000 GET user:1
redis-cli -c -p 7000 CLUSTER SLOTS # 槽与节点映射,客户端据此建路由表
redis-cli -c -p 7000 CLUSTER KEYSLOT user:1 # 单独确认某个键的槽号
redis-cli --cluster check 10.0.0.11:7000 # 从任意节点视角体检拓扑与槽覆盖重定向与客户端行为
| 返回信息 | 服务端含义 | 客户端应做 |
|---|---|---|
| MOVED 3999 10.0.0.12:7000 | 槽已归属该节点 | 更新本地映射表后向该节点重发命令 |
| ASK 3999 10.0.0.12:7000 | 槽正在迁移,键暂存在目标节点 | 对该节点先发 ASKING,再重发本次命令,不改映射表 |
| CLUSTERDOWN | 集群不可用,槽未分配完整或多数派丢失 | 不要无上限重试,需人工介入排查 |
| CROSSSLOT | 多 key 命令中的键不在同一槽 | 改造键命名用同一哈希标签,而不是反复重试 |
| TRYAGAIN | 槽迁移期间的多 key 命令暂不可执行 | 短暂退避后重试一次 |
路由刷新策略直接决定切换期间的错误率:部分客户端遇到 MOVED 只更新单个槽,部分会整体重拉 CLUSTER SLOTS。故障切换后如果出现短时间大量报错又自行恢复,通常就是拓扑刷新在起作用,先查客户端日志与拓扑刷新间隔,再判断服务端是否切换失败。
用不支持集群的客户端连集群,或把地址写死成某一个节点,扩容与切换后会出现持续报错或只访问到部分数据。连接必须基于种子节点自动发现,连接池也要能感知节点上下线并淘汰失效连接。