知识卡片
非对称集群:角色分工与重新分配,及相比负载均衡集群多出的两层复杂度
内容
和[[负载均衡集群:任务分配策略与状态检测两个设计关键点]]里”每台服务器角色都一样”不同,非对称集群里不同服务器承担不同角色、执行不同职责,最常见的形式就是Master-Slave:部分任务只能由Master服务器执行,部分任务只能由Slave服务器执行。具体设计上,集群需要先通过某种方式区分角色(比如用ZAB算法选举,或者简单粗暴地取当前存活服务器里节点ID最小的那台当Master),任务分配器再把不同类型的任务发给不同角色(比如计算任务A发给Master、计算任务B发给Slave);当特定角色的服务器故障时,处理方式也不一样——如果是Master故障,需要从剩下的Slave里重新指定一台升级为Master;如果是Slave故障,则不需要重新分配角色,直接把这台故障机从集群里剔除即可。非对称集群相比负载均衡集群,复杂度多出两层:一是任务分配策略更复杂——不能像负载均衡集群那样简单轮询随机分配,而是要先把任务按类型划分清楚,再分别发给对应角色的节点;二是角色分配策略的实现更复杂——判断谁该当Master、Master挂了怎么重新选,往往需要ZAB、Raft这类相对复杂的一致性算法来支撑Leader选举。以ZooKeeper为例可以对照理解这两层复杂度具体落地成什么样:任务分配这一层,ZooKeeper里不存在一个独立的任务分配器节点,每个Server自己就是任务分配器——Follower节点收到请求后自己判断,是写请求就转发给Leader,是读请求就自己直接处理;角色指定这一层,ZooKeeper用ZAB算法来选举Leader,一旦Leader故障,所有Follower节点会先暂停对外的读写服务、进入选举流程,直到新Leader选出来才恢复对客户端的服务。
结构图:
flowchart TB
A["非对称集群(Master-Slave)"]
A --> B["角色区分:ZAB算法选举<br/>或取存活节点中ID最小者"]
B --> C["任务分配器按任务类型<br/>发给对应角色(如任务A给Master/任务B给Slave)"]
C --> D["Master故障:<br/>从Slave中重新指定一台升级为Master"]
C --> E["Slave故障:<br/>直接剔除,无需重新分配角色"]
A --> F["相比负载均衡集群多出两层复杂度"]
F --> F1["①任务分配策略更复杂:需按类型划分任务"]
F --> F2["②角色分配实现更复杂:<br/>需ZAB/Raft等算法支撑Leader选举"]
F1 --> G["ZooKeeper实例:<br/>Follower自身即任务分配器(写转发/读自处理)<br/>ZAB选举Leader,选举期间暂停读写"]
F2 --> G
参考来源
- 位置:《从零开始学架构》第27讲《如何设计计算高可用架构?》"集群"之"非对称集群"(源文件:_epub-src/OEBPS/text00002.html)
- 结论依据:原文说明"当指定类型的服务器故障时,需要重新分配角色。例如,Master 服务器故障后,需要将剩余的 Slave 服务器中的一个重新指定为 Master 服务器;如果是 Slave 服务器故障,则并不需要重新分配角色",并列出"任务分配策略更加复杂……角色分配策略实现比较复杂……可能需要使用 ZAB、Raft 这类复杂的算法",及ZooKeeper具体实现"每个 Server 都是任务分配器……ZooKeeper 通过 ZAB 算法来选举 Leader,当 Leader 故障后,所有的 Follower 节点会暂停读写操作,开始进行选举",直接支撑本卡片结论与结构图。
- 原始内容:当指定类型的服务器故障时,需要重新分配角色……非对称集群相比负载均衡集群,设计复杂度主要体现在两个方面……ZooKeeper 通过 ZAB 算法来选举 Leader,当 Leader 故障后,所有的 Follower 节点会暂停读写操作,开始进行选举,直到新的 Leader 选举出来后才继续对 Client 提供服务。