Routing in Distributed Systems
question
分布式系统中的路由有谁来负责?客户端还是服务端?
answer
两种方式都存在,要看具体系统的设计选择
客户端路由 client-side routing
客户端自己决定请求发到哪个节点,例如
通过一致性哈希(Consistent Hashing)或某种分片规则定位到具体节点
通常客户端会缓存一份集群拓扑信息或元数据
代表系统:
Cassandra
Riak
Kafka Producer(可以自己决定发送到哪个 partition)
优点:
请求路径短,直接到目标节点
减少跳转、中间层压力
缺点:
客户端实现复杂,要感知集群拓扑变化
拓扑变化(比如扩容)可能导致客户端缓存失效,需要有刷新机制
服务端路由 server-side routing
客户端只连接某个入口节点(称为 router、coordinator、proxy 等),再由这个节点在集群内部路由转发。
代表系统:
MongoDB(mongos)
TiDB(SQL 层接入)
HBase(通过 RegionServer)
Elasticsearch(coordinating node)
优点:
客户端简单,不需要关心数据分布
系统可以集中处理元数据、负载均衡
缺点:
增加一跳,可能引入性能瓶颈
入口节点成为潜在的热点或单点故障点(需高可用设计)
对比例子
Kafka(客户端路由):
Kafka 的 producer 会从 broker 获取元数据,然后根据 topic 的 partition 和 key 做 hash,直接发送消息到对应的 broker。这样中间没有 proxy,性能高。
MongoDB(服务端路由):
MongoDB 分片集群中,客户端连接 mongos,而不是直接连接 shard。mongos 是查询协调器,接收请求后根据 chunk 的分布信息,分发请求到对应 shard 上。
Redis Cluster
数据分片
Redis Cluster 将整个 key 空间划分为 16384 个 slot(称为 哈希槽)。
每个 key 通过
CRC16(key) % 16384得到其 slot 编号。每个节点负责其中的一部分 slot。
路由流程(客户端侧):
客户端第一次连接时 ,会从任意一个 Redis 节点获取集群拓扑信息(即所有 slot 分布在哪些节点)。
计算 slot :发送命令时,客户端根据 key 计算它属于哪个 slot。
选择节点 :根据 slot 到节点的映射,直接将命令发送到对应的节点。
如果客户端路由错了(比如映射信息过期),Redis 节点会返回:
-MOVED:告诉客户端该 slot 已经迁移到其他节点,客户端需更新 slot 映射表。-ASK:表示 slot 正在迁移过程中,客户端暂时重定向到新节点(但不更新本地映射)。
客户端需要支持这类重试和 slot 映射更新逻辑。
Redis Cluster 节点如何管理 slot?
Redis Cluster 将 16384 个 slot 显式分配给集群中的节点。每个节点会维护一份 slot -> 节点 的映射信息,并参与集群协议,确保这个映射在整个集群中是一致的。
一、slot 是怎么分配给节点的?
在 Redis Cluster 启动或扩容时,管理员手动(或使用工具如 redis-cli --cluster create)将 slot 分配给节点。比如:
节点 A:0 ~ 5460
节点 B:5461 ~ 10922
节点 C:10923 ~ 16383
Redis 每个主节点(master)会维护自己负责的 slot 范围,并在 CLUSTER SLOTS、CLUSTER NODES 等命令中向外暴露这些信息。
二、slot 元数据存储在哪?
每个 Redis 节点内部维护一张哈希表:
此外,每个节点还记录所有其他节点的 IP、端口、角色(master/slave)、健康状态等集群元数据。
三、节点之间如何同步 slot 信息?
Redis Cluster 节点通过 gossip 协议(定期交换心跳包和元数据)相互同步 cluster 状态,包括:
每个节点负责的 slot 范围
节点是否宕机
主从关系是否发生切换
slot 是否在迁移(migrating/importing)
这些信息帮助节点共同维持整个集群的一致视图。
四、slot 迁移是怎么进行的?(Re-sharding)
当你想把部分 slot 从节点 A 移动到节点 B:
设置状态标志:
A 设置 slot 为
migratingB 设置该 slot 为
importing
通过
CLUSTER SETSLOT命令通知集群 slot 状态变化搬迁数据:
客户端或管理员使用 redis-cli --cluster reshard 工具
将指定 slot 上的 key 从 A 拉到 B,通常用 MIGRATE 命令实现
完成后 slot 属于 B,更新集群状态
客户端这时会收到 ASK 响应,提示临时重定向请求到目标节点。
五、如何查看 slot 分布?
总结对比
方式 | 特点 | 代表系统 |
|---|---|---|
客户端路由 | 高性能、需要客户端维护路由信息 | Cassandra、Kafka、Couchbase |
服务端路由(代理) | 简化客户端逻辑、可集中控制负载,但增加中间跳转 | MongoDB、TiDB、HBase、ES |