知识卡片
请求路由三种方案的共同难题是谁来同步分区节点映射
内容
分区随[[分区再平衡策略从反面教材hash-mod-N到固定分区与动态分区]]不断在节点间搬动, 客户端要读写某个键,必须先知道该连哪个节点——这是”服务发现”问题的一种,不止数据库 才有。解决路径有三种。方案一:客户端可以连任意节点(比如经轮询负载均衡器),如果 恰好连到的节点拥有目标分区就直接处理,否则该节点把请求转发给真正拥有该分区的节点、 拿到结果再转发回客户端——Cassandra和Riak走这条路,节点间用流言协议(gossip protocol)互相传播集群状态变化,好处是不依赖任何外部协调服务,代价是把这部分复杂度 放进了数据库节点本身。方案二:所有客户端请求先统一发到一个独立的路由层,由它决定 该转给哪个节点,路由层本身不处理任何请求,只负责按分区做负载均衡——LinkedIn的 Espresso(用Helix做集群管理)和MongoDB(mongos守护进程配自己的config server)都是 这种架构。方案三:让客户端自己知道分区到节点的映射,直接连正确的节点,不经过任何 中介。三种方案共同的核心难题不是”怎么路由”,而是”负责路由决策的那个组件,怎么第一 时间知道分区-节点映射发生了变化”——因为这本质是一个要求所有参与者达成共识的分布式 问题,很难正确实现。许多系统(HBase、SolrCloud、Kafka)选择依赖ZooKeeper这类独立 协调服务:每个节点在ZooKeeper里注册自己,ZooKeeper维护权威的分区-节点映射,路由层 或分区感知客户端订阅这份信息,一旦分配变化就会被推送通知,从而保持路由信息最新。
结构图:
flowchart LR
A[方案一: 客户端连任意节点] --> A1[节点自己判断是否拥有目标分区]
A1 --> A2[不是则转发给正确节点再回传]
A2 -.Cassandra/Riak用gossip协议同步状态, 不依赖外部协调.-> A2
B[方案二: 独立路由层] --> B1[所有请求先到路由层, 由其转发]
B1 -.依赖ZooKeeper等协调服务获知映射变化.-> B1
C[方案三: 客户端自知映射] --> C1[直连正确节点, 无中介]
参考来源
- 位置:《数据密集型应用系统设计》第六章《分区》"请求路由"(源文件:
_epub-src/ch6_split_006.html)
- 结论依据:原文列出客户端连任意节点由其转发、统一路由层、客户端自知映射三种
请求路由方案,说明Cassandra/Riak用流言协议自主传播集群状态、HBase等依赖
ZooKeeper这类独立协调服务维护分区节点映射,直接支撑本卡片的结构梳理。
- 原始内容:允许客户联系任何节点……如果该节点恰巧拥有请求的分区,则它可以直接
处理该请求;否则,它将请求转发到适当的节点……首先将所有来自客户端的请求发送到
路由层……要求客户端知道分区和节点的分配……许多分布式数据系统都依赖于一个独立
的协调服务,比如ZooKeeper来跟踪集群元数据。