2.2 集群模式:让三位法官同时开庭


文档摘要

2.2 集群模式:让三位法官同时开庭 本节摘要:集群部署的核心是 myid 与 server 列表的咬合、投票选出 Leader、以及奇数台机器背后的多数派算术。本节带你在本机或三台服务器上完成三节点部署,并亲手停掉 Leader 亲眼目睹一次换庭。 为什么是三台,而不是两台 先算一笔账再动手。ZooKeeper 的每次写入需要多数派(过半)确认,记总台数为 N,可容忍故障数为 N 除以 2 向下取整。三台容一(三台中挂一台,剩两台仍过半),五台容二,四台也只容一——四台的成本换来和三台一样的容错,这就是生产部署清一色奇数的全部原因。两台更尴尬:挂任何一台,剩下一台都凑不出多数派,可用性与单机无异,却多了一致性协议的开销。所以集群规模从三起步,按"要容几台故障"反推:容一台三台,容两台五台。

2.2 集群模式:让三位法官同时开庭

本节摘要:集群部署的核心是 myid 与 server 列表的咬合、投票选出 Leader、以及奇数台机器背后的多数派算术。本节带你在本机或三台服务器上完成三节点部署,并亲手停掉 Leader 亲眼目睹一次换庭。

为什么是三台,而不是两台

先算一笔账再动手。ZooKeeper 的每次写入需要多数派(过半)确认,记总台数为 N,可容忍故障数为 N 除以 2 向下取整。三台容一(三台中挂一台,剩两台仍过半),五台容二,四台也只容一——四台的成本换来和三台一样的容错,这就是生产部署清一色奇数的全部原因。两台更尴尬:挂任何一台,剩下一台都凑不出多数派,可用性与单机无异,却多了一致性协议的开销。所以集群规模从三起步,按"要容几台故障"反推:容一台三台,容两台五台。

部署拓扑上还有两条军规。第一,机器分散在不同物理机、不同机架甚至不同交换机下——把三台部署在同一台宿主机的三个容器里,宿主机一抖三台全灭,多数派荡然无存。第二,主机名与端口提前规划好,集群配置里出现 IP 与主机名混用是排障时的经典噩梦。

三节点部署实操

本机模拟用三个目录、三个端口;真实环境把目录换成三台机器、端口统一为 2181,步骤完全一致。

图:三节点集群拓扑与角色分布

图:三节点集群拓扑与角色分布

每台机器的配置分三步:写 zoo.cfg、写 myid、逐台启动验证。

# 三台机器共用的 zoo.cfg(server 列表三台完全一致) tickTime=2000 initLimit=10 # 新节点连上 Leader 后,等多少个 tick 完成初始化同步 syncLimit=5 # 正常运行时,Leader 与 Follower 之间允许多少个 tick 的延迟 dataDir=/var/lib/zookeeper clientPort=2181 # server.编号=主机名:选举通信端口:提案广播端口 server.1=node1:2888:3888 server.2=node2:2888:3888 server.3=node3:2888:3888
# 每台机器各自写 myid——内容必须与 server.N 的 N 一致 $ echo 1 > /var/lib/zookeeper/myid # 在 node1 上执行 $ echo 2 > /var/lib/zookeeper/myid # 在 node2 上执行 $ echo 3 > /var/lib/zookeeper/myid # 在 node3 上执行 # 三台分别启动,然后逐台验证角色 $ bin/zkServer.sh start $ bin/zkServer.sh status Mode: leader # node1 输出(谁当选有随机性,两台 follower 即正常)

myid 与 server 列表的咬合关系值得单独强调:server.N 声明"编 N 的法官是谁",myid 声明"我是 N"。两者对不上,节点启动时会报 myid file is missing 或直接互不认识。2888 是 Leader 向 Follower 推送提案的端口,3888 是选举时互相拉票的端口,防火墙必须放行——三台之间 3888 不通时,你会看到日志里反复出现 Cannot open channel to 2 at election address,而集群永远选不出 Leader。

亲手换一次庭

部署的意义在验证。把 Leader 停掉,看剩下的机器如何自我修复:

# 在当前 Leader(假设 node1)上执行 $ bin/zkServer.sh stop # 立刻到 node2、node3 上查看状态,几秒内完成重新选举 $ bin/zkServer.sh status Mode: leader # node2 或 node3 之一接任 Mode: follower # 客户端此时把连接切到幸存节点,读写照常 $ bin/zkCli.sh -server node3:2181 [zk] get /hello world # 数据未丢:多数派已持久化的提案依然在案

这次实验演示的正是第四章 4.2 节要展开的快速选举:幸存的两台交换投票、多数认可后立即上任,全程秒级。而如果你把三台停掉两台,会发现幸存的那台 statusError contacting service——它不是坏了,是在拒绝服务,呼应 1.3 节的 CP 承诺。

要点回顾

  • 奇数军规的由来:过半表决下,2N 台与 2N-1 台容错相同,按目标容错反推规模,三台起步。
  • myid 与 server.N 是一对钥匙:前者自报编号,后者登记名单,错一个字符集群就散伙。
  • 两组端口各司其职:2888 传提案,3888 拉选票,防火墙漏放行是选不出 Leader 的头号原因。
  • 换庭实验必做:停 Leader 看秒级接任,停两台看整体罢工,机制课之前先建立直观。

常见疑问

问:能否加 Observer 凑数? 可以但别混淆——Observer 不参与投票,只是读扩展件,凑不进多数派。读流量大的集群用"三 Follower 加若干 Observer"扩展读能力,2.3 节的配置里会给出开关。

法庭搭好了,但配置文件里还有一串参数没读懂,下一节逐项过堂。

Observer:读扩展的编外席

集群读流量大到三台 Follower 吃不消时,正确姿势不是加投票节点(多数派会变大、写路径变慢),而是加 Observer:它同步数据、服务读请求,但不参与选举与表决。配置两行即可:

# zoo.cfg 中追加 Observer 成员,并用分组声明其不投票 server.4=observer1:2888:3888:observer # 客户端照常连 Observer 的 clientPort,读请求本地应答 # 验证:state 输出为 observer
$ echo srvr | nc observer1 2181 | findstr Mode Mode: observer

Observer 的适用判据很清晰:读扩展需求真实存在且写流量不低时用它;纯粹"机器多显得可靠"而加 Observer 则毫无意义——它不在多数派里,对容错没有贡献。

部署验收清单

生产交接前把这张单子过一遍,每一条都对应本章的一个坑位:myid 与 server.N 一一对应;三台之间 2888 与 3888 双向连通;机器分布在不同机架或宿主机;时钟同步服务在跑;tickTime 体系按机房延迟校准过;停一台验证换届、停两台验证罢工的实验都有记录。清单不通过不上线,这是 6.4 节运维体系的第一道闸。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U