redis-plus-plus单节点连接不处理MOVED/ASK重定向,需改用Cluster类并配置ConnectionPool;读从节点须设ReadStrategy::SLAVE或NEAREST;故障恢复依赖拓扑刷新或手动cluster.refresh();CROSSSLOT错误源于多key跨槽,须用{}确保同槽。

用 redis-plus-plus 连 Redis 集群时,为什么写请求总报 MOVED 或 ASK 错误?
因为原生 redis-plus-plus 的单节点连接(Redis 类)不自动处理集群重定向。它把集群当单机用,发请求到错误节点就会返回 MOVED 12345 10.0.1.5:6379 —— 你得自己解析、跳转、重试。
正确做法是改用集群专用客户端:Cluster 类。它内置 Slot 计算、节点拓扑发现和自动重定向,但要注意初始化方式:
- 必须用
ConnectionPool管理连接,不能传单个ConnectionOptions - 初始化时至少提供一个可用的集群节点地址(哪怕只是 seed node),例如:
Cluster("redis://10.0.1.1:7000", ConnectionPoolOptions{}) - 首次连接会自动
CLUSTER SLOTS拉取全量拓扑,后续请求按 key 的 CRC16 % 16384 自动路由到对应主节点
怎么让读请求走从节点,实现读写分离?
redis-plus-plus 的 Cluster 默认只连主节点(Role::MASTER),读写都在主上。要读从节点,必须显式设置 Cluster::ReadStrategy:
- 设为
ReadStrategy::SLAVE:读请求随机发给该 Slot 对应的任一从节点(要求集群开启slave-read-only yes) - 设为
ReadStrategy::NEAREST:客户端会探测各节点延迟,选网络最近的从节点(需开启enable_latency_monitor并定期LATENCY LATEST) - 注意:写请求永远只发主节点,不受此配置影响;
GET、HGET等只读命令才走从节点
示例:
Cluster cluster("redis://10.0.1.1:7000", ConnectionPoolOptions{}, ClusterOptions{.read_strategy = ReadStrategy::SLAVE});立即学习“C++免费学习笔记(深入)”;
多副本高可用下,节点故障时客户端怎么恢复?
集群模式下,主节点宕机触发故障转移后,从节点升主、拓扑变更。客户端不会自动感知,除非你主动刷新或等下一次 CLUSTER SLOTS 失败后重试。
-
Cluster内部有拓扑缓存,默认 5 秒刷新一次(可配ClusterOptions::topology_refresh_interval) - 更可靠的做法是捕获
ReplyError异常中的CLUSTERDOWN或TRYAGAIN,然后调用cluster.refresh();强制重拉拓扑 - 连接池本身不自动剔除失效节点,需靠
ConnectionPoolOptions::connection_lifetime和idle_timeout控制连接复用周期,避免长连接卡在已下线节点上
为什么某些 key 的读写总是失败,且错误信息里带 CROSSSLOT?
Redis 集群不支持跨 Slot 的多 key 操作(如 MGET a b c 中 a、b、c 不在同一 Slot)。redis-plus-plus 的 Cluster 会提前校验,直接抛 CrossSlotError 异常,而不是发到服务端再被拒。
- 解决办法只有两个:拆成单 key 请求(性能差),或确保多个 key 属于同一 Slot(用
{...}标签强制哈希,如MGET {user:1001}:name {user:1001}:email) - 注意:Lua 脚本也受此限制,
EVAL所有 KEYS 必须落在同一 Slot,否则报错 - 别依赖客户端“智能路由”,它只做 Slot 映射,不做语义分析 —— 错误在你构造命令时就已注定
真实部署中,Slot 分布和 key 命名策略比客户端配置更关键。没想清楚 {} 怎么打,换什么客户端都救不了。


















