ZooKeeper 集群内部通信机制深度解析:端口、协议与数据同步
-
- 一、集群通信概述
-
- 1.1 为什么要进行内部通信?
- 1.2 通信基础:TCP 长连接
- 二、集群通信的三类核心端口
-
- 2.1 客户端端口(2181)
- 2.2 集群通信端口(2888)
- 2.3 选举端口(3888)
- 2.4 端口通信示意图
- 三、通信的核心协议:ZAB
-
- 3.1 消息类型定义
- 3.2 基于 FIFO 信道的顺序保证
- 四、Leader 与 Follower 的通信流程
-
- 4.1 正常运行时的心跳检测
- 4.2 事务提案的完整通信流程
- 五、Leader 选举时的通信
-
- 5.1 选举通信端口(3888)的作用
- 5.2 选举完成后的数据同步
- 六、Observer 节点的特殊通信
-
- 6.1 Observer 的通信特点
- 6.2 Observer 的配置
- 七、通信中的关键数据结构
-
- 7.1 ZXID:全局有序的事务标识
- 7.2 LearnerHandler:处理对端连接的组件
- 八、通信故障处理
-
- 8.1 连接断开处理
- 8.2 超时配置
- 九、总结
-
- 9.1 通信要点回顾
- 9.2 通信流程全景图
- 9.3 一句话总结
|
🌺The Begin🌺点点关注,收藏不迷路🌺 |
摘要:ZooKeeper 集群之所以能实现高可用和数据一致性,核心在于服务器之间有一套精密高效的通信机制。从底层的 TCP 连接,到上层的 ZAB 协议,再到不同角色之间的数据同步,每个环节都经过精心设计。本文将深入剖析 ZooKeeper 集群内部的通信原理,包括通信端口、消息类型、Leader 与 Follower 的交互流程以及数据同步策略。
一、集群通信概述
1.1 为什么要进行内部通信?
在 ZooKeeper 集群中,服务器之间需要频繁通信以实现以下目标:
| 数据同步 | 保证所有节点的数据视图一致 |
| Leader 选举 | 在 Leader 故障时快速选出新 Leader |
| 心跳检测 | 监控各节点的存活状态 |
| 事务提案 | Leader 将写操作广播给所有 Follower |
| 投票确认 | Follower 对事务提案进行投票 |
#mermaid-svg-Ax00uhGBwaUAGCkc{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ax00uhGBwaUAGCkc .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ax00uhGBwaUAGCkc .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ax00uhGBwaUAGCkc .error-icon{fill:#552222;}#mermaid-svg-Ax00uhGBwaUAGCkc .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ax00uhGBwaUAGCkc .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ax00uhGBwaUAGCkc .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ax00uhGBwaUAGCkc .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ax00uhGBwaUAGCkc .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ax00uhGBwaUAGCkc .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ax00uhGBwaUAGCkc .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ax00uhGBwaUAGCkc .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ax00uhGBwaUAGCkc .marker.cross{stroke:#333333;}#mermaid-svg-Ax00uhGBwaUAGCkc svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ax00uhGBwaUAGCkc p{margin:0;}#mermaid-svg-Ax00uhGBwaUAGCkc .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Ax00uhGBwaUAGCkc .cluster-label text{fill:#333;}#mermaid-svg-Ax00uhGBwaUAGCkc .cluster-label span{color:#333;}#mermaid-svg-Ax00uhGBwaUAGCkc .cluster-label span p{background-color:transparent;}#mermaid-svg-Ax00uhGBwaUAGCkc .label text,#mermaid-svg-Ax00uhGBwaUAGCkc span{fill:#333;color:#333;}#mermaid-svg-Ax00uhGBwaUAGCkc .node rect,#mermaid-svg-Ax00uhGBwaUAGCkc .node circle,#mermaid-svg-Ax00uhGBwaUAGCkc .node ellipse,#mermaid-svg-Ax00uhGBwaUAGCkc .node polygon,#mermaid-svg-Ax00uhGBwaUAGCkc .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ax00uhGBwaUAGCkc .rough-node .label text,#mermaid-svg-Ax00uhGBwaUAGCkc .node .label text,#mermaid-svg-Ax00uhGBwaUAGCkc .image-shape .label,#mermaid-svg-Ax00uhGBwaUAGCkc .icon-shape .label{text-anchor:middle;}#mermaid-svg-Ax00uhGBwaUAGCkc .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Ax00uhGBwaUAGCkc .rough-node .label,#mermaid-svg-Ax00uhGBwaUAGCkc .node .label,#mermaid-svg-Ax00uhGBwaUAGCkc .image-shape .label,#mermaid-svg-Ax00uhGBwaUAGCkc .icon-shape .label{text-align:center;}#mermaid-svg-Ax00uhGBwaUAGCkc .node.clickable{cursor:pointer;}#mermaid-svg-Ax00uhGBwaUAGCkc .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Ax00uhGBwaUAGCkc .arrowheadPath{fill:#333333;}#mermaid-svg-Ax00uhGBwaUAGCkc .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Ax00uhGBwaUAGCkc .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Ax00uhGBwaUAGCkc .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ax00uhGBwaUAGCkc .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Ax00uhGBwaUAGCkc .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ax00uhGBwaUAGCkc .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Ax00uhGBwaUAGCkc .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Ax00uhGBwaUAGCkc .cluster text{fill:#333;}#mermaid-svg-Ax00uhGBwaUAGCkc .cluster span{color:#333;}#mermaid-svg-Ax00uhGBwaUAGCkc div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Ax00uhGBwaUAGCkc .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Ax00uhGBwaUAGCkc rect.text{fill:none;stroke-width:0;}#mermaid-svg-Ax00uhGBwaUAGCkc .icon-shape,#mermaid-svg-Ax00uhGBwaUAGCkc .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ax00uhGBwaUAGCkc .icon-shape p,#mermaid-svg-Ax00uhGBwaUAGCkc .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Ax00uhGBwaUAGCkc .icon-shape rect,#mermaid-svg-Ax00uhGBwaUAGCkc .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ax00uhGBwaUAGCkc .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Ax00uhGBwaUAGCkc .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Ax00uhGBwaUAGCkc :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
ZooKeeper 集群内部通信全景
1. 心跳检测
1. 心跳检测
1. 心跳检测
2. 事务提案
2. 事务提案
2. 事务提案
3. 投票 ACK
3. 投票 ACK
3. 投票 ACK
4. 提交 COMMIT
4. 提交 COMMIT
4. 提交 COMMIT
5. 选举通信
5. 选举通信
5. 选举通信
Leader 节点
Follower1
Follower2
Follower3
1.2 通信基础:TCP 长连接
ZooKeeper 集群内部的所有通信都基于 TCP 长连接 。选择 TCP 的原因在于其天然提供的特性:
| 有序交付 | 数据按照发送顺序交付,保证消息的 FIFO 顺序 |
| 可靠传输 | 丢包重传机制保证消息不会丢失 |
| 连接状态 | 连接关闭后不再接收消息,便于故障检测 |
ZooKeeper 协议设计假设服务器之间可以构建点对点的 FIFO 通道,TCP 完美满足了这一需求 。
二、集群通信的三类核心端口
在 ZooKeeper 的配置文件 zoo.cfg 中,我们通常看到这样的配置:
server.1=192.168.1.10:2888:3888
server.2=192.168.1.11:2888:3888
server.3=192.168.1.12:2888:3888
这里包含了三个关键端口,各自承担不同的通信职责 。
2.1 客户端端口(2181)
- 作用:ZooKeeper 服务器监听客户端连接的端口
- 通信方向:客户端 → 服务器
- 说明:虽然这是客户端接入的端口,但服务器内部也需要知道自己的服务端口。此端口不在集群内部通信中使用。
2.2 集群通信端口(2888)
- 作用:Follower 连接到 Leader 的端口,用于数据同步、事务提案转发、心跳检测
- 通信方向:Follower → Leader(以及 Leader → Follower)
- 默认值:2888
这是集群内部最繁忙的端口,所有事务性的交互都通过此端口完成 。
2.3 选举端口(3888)
- 作用:集群Leader 选举时,服务器之间相互通信的端口
- 通信方向:服务器 ↔ 服务器(全互联)
- 默认值:3888
当集群启动或 Leader 故障时,所有节点通过此端口交换投票信息,选举出新的 Leader 。
2.4 端口通信示意图
#mermaid-svg-QIQYaMqDIFEJJV0J{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QIQYaMqDIFEJJV0J .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QIQYaMqDIFEJJV0J .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QIQYaMqDIFEJJV0J .error-icon{fill:#552222;}#mermaid-svg-QIQYaMqDIFEJJV0J .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QIQYaMqDIFEJJV0J .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QIQYaMqDIFEJJV0J .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QIQYaMqDIFEJJV0J .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QIQYaMqDIFEJJV0J .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QIQYaMqDIFEJJV0J .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QIQYaMqDIFEJJV0J .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QIQYaMqDIFEJJV0J .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QIQYaMqDIFEJJV0J .marker.cross{stroke:#333333;}#mermaid-svg-QIQYaMqDIFEJJV0J svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QIQYaMqDIFEJJV0J p{margin:0;}#mermaid-svg-QIQYaMqDIFEJJV0J .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-QIQYaMqDIFEJJV0J .cluster-label text{fill:#333;}#mermaid-svg-QIQYaMqDIFEJJV0J .cluster-label span{color:#333;}#mermaid-svg-QIQYaMqDIFEJJV0J .cluster-label span p{background-color:transparent;}#mermaid-svg-QIQYaMqDIFEJJV0J .label text,#mermaid-svg-QIQYaMqDIFEJJV0J span{fill:#333;color:#333;}#mermaid-svg-QIQYaMqDIFEJJV0J .node rect,#mermaid-svg-QIQYaMqDIFEJJV0J .node circle,#mermaid-svg-QIQYaMqDIFEJJV0J .node ellipse,#mermaid-svg-QIQYaMqDIFEJJV0J .node polygon,#mermaid-svg-QIQYaMqDIFEJJV0J .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QIQYaMqDIFEJJV0J .rough-node .label text,#mermaid-svg-QIQYaMqDIFEJJV0J .node .label text,#mermaid-svg-QIQYaMqDIFEJJV0J .image-shape .label,#mermaid-svg-QIQYaMqDIFEJJV0J .icon-shape .label{text-anchor:middle;}#mermaid-svg-QIQYaMqDIFEJJV0J .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QIQYaMqDIFEJJV0J .rough-node .label,#mermaid-svg-QIQYaMqDIFEJJV0J .node .label,#mermaid-svg-QIQYaMqDIFEJJV0J .image-shape .label,#mermaid-svg-QIQYaMqDIFEJJV0J .icon-shape .label{text-align:center;}#mermaid-svg-QIQYaMqDIFEJJV0J .node.clickable{cursor:pointer;}#mermaid-svg-QIQYaMqDIFEJJV0J .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QIQYaMqDIFEJJV0J .arrowheadPath{fill:#333333;}#mermaid-svg-QIQYaMqDIFEJJV0J .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QIQYaMqDIFEJJV0J .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QIQYaMqDIFEJJV0J .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QIQYaMqDIFEJJV0J .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QIQYaMqDIFEJJV0J .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QIQYaMqDIFEJJV0J .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QIQYaMqDIFEJJV0J .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QIQYaMqDIFEJJV0J .cluster text{fill:#333;}#mermaid-svg-QIQYaMqDIFEJJV0J .cluster span{color:#333;}#mermaid-svg-QIQYaMqDIFEJJV0J div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QIQYaMqDIFEJJV0J .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QIQYaMqDIFEJJV0J rect.text{fill:none;stroke-width:0;}#mermaid-svg-QIQYaMqDIFEJJV0J .icon-shape,#mermaid-svg-QIQYaMqDIFEJJV0J .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QIQYaMqDIFEJJV0J .icon-shape p,#mermaid-svg-QIQYaMqDIFEJJV0J .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QIQYaMqDIFEJJV0J .icon-shape rect,#mermaid-svg-QIQYaMqDIFEJJV0J .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QIQYaMqDIFEJJV0J .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QIQYaMqDIFEJJV0J .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QIQYaMqDIFEJJV0J :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Follower 节点2
Follower 节点1
ZooKeeper 节点
2181
2181
2181
2888 数据同步
2888 数据同步
3888 选举通信
3888 选举通信
3888 选举通信
Leader 节点
端口: 2181/2888/3888
Follower1
端口: 2181/2888/3888
Follower2
端口: 2181/2888/3888
客户端
三、通信的核心协议:ZAB
ZooKeeper 内部通信的逻辑由 ZAB(ZooKeeper Atomic Broadcast)协议 驱动 。ZAB 协议分为两个主要阶段:领导激活(Leader Activation) 和 活动消息传递(Active Messaging)。
3.1 消息类型定义
在 ZAB 协议中,服务器之间交换的主要消息类型包括 :
| PROPOSAL | Leader | Follower | 提出一个新的事务提案 |
| ACK | Follower | Leader | 确认收到并持久化了提案 |
| COMMIT | Leader | Follower | 通知可以提交该事务 |
| PING | Leader/Follower | 对方 | 心跳检测 |
| FOLLOWERINFO | Follower | Leader | 连接时发送自己的 lastZxid |
| LEADERINFO | Leader | Follower | 发送 Leader 的 epoch 信息 |
| NEWLEADER | Leader | Follower | 通知自己成为新 Leader |
| UPTODATE | Leader | Follower | 通知数据已同步完成 |
3.2 基于 FIFO 信道的顺序保证
ZAB 协议充分利用了 TCP 的 FIFO 特性,确保所有通信按顺序进行 :
- Leader 使用相同的顺序向所有 Follower 发送提案,这个顺序与请求接收顺序一致
- Follower 按接收顺序处理消息,因此 ACK 也会按顺序返回
- 一旦超过半数的 Follower 对某个消息进行了 ACK,Leader 就会按顺序发送 COMMIT
- COMMIT 同样按顺序处理,确保消息提交顺序全局一致
四、Leader 与 Follower 的通信流程
4.1 正常运行时的心跳检测
Follower
Leader
Follower
Leader
#mermaid-svg-BpoRLpnnhSQQN9ik{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-BpoRLpnnhSQQN9ik .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-BpoRLpnnhSQQN9ik .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-BpoRLpnnhSQQN9ik .error-icon{fill:#552222;}#mermaid-svg-BpoRLpnnhSQQN9ik .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-BpoRLpnnhSQQN9ik .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-BpoRLpnnhSQQN9ik .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-BpoRLpnnhSQQN9ik .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-BpoRLpnnhSQQN9ik .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-BpoRLpnnhSQQN9ik .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-BpoRLpnnhSQQN9ik .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-BpoRLpnnhSQQN9ik .marker{fill:#333333;stroke:#333333;}#mermaid-svg-BpoRLpnnhSQQN9ik .marker.cross{stroke:#333333;}#mermaid-svg-BpoRLpnnhSQQN9ik svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-BpoRLpnnhSQQN9ik p{margin:0;}#mermaid-svg-BpoRLpnnhSQQN9ik .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-BpoRLpnnhSQQN9ik text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-BpoRLpnnhSQQN9ik .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-BpoRLpnnhSQQN9ik .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-BpoRLpnnhSQQN9ik .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-BpoRLpnnhSQQN9ik .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-BpoRLpnnhSQQN9ik #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-BpoRLpnnhSQQN9ik .sequenceNumber{fill:white;}#mermaid-svg-BpoRLpnnhSQQN9ik #sequencenumber{fill:#333;}#mermaid-svg-BpoRLpnnhSQQN9ik #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-BpoRLpnnhSQQN9ik .messageText{fill:#333;stroke:none;}#mermaid-svg-BpoRLpnnhSQQN9ik .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-BpoRLpnnhSQQN9ik .labelText,#mermaid-svg-BpoRLpnnhSQQN9ik .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-BpoRLpnnhSQQN9ik .loopText,#mermaid-svg-BpoRLpnnhSQQN9ik .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-BpoRLpnnhSQQN9ik .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-BpoRLpnnhSQQN9ik .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-BpoRLpnnhSQQN9ik .noteText,#mermaid-svg-BpoRLpnnhSQQN9ik .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-BpoRLpnnhSQQN9ik .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-BpoRLpnnhSQQN9ik .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-BpoRLpnnhSQQN9ik .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-BpoRLpnnhSQQN9ik .actorPopupMenu{position:absolute;}#mermaid-svg-BpoRLpnnhSQQN9ik .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-BpoRLpnnhSQQN9ik .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-BpoRLpnnhSQQN9ik .actor-man circle,#mermaid-svg-BpoRLpnnhSQQN9ik line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-BpoRLpnnhSQQN9ik :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
loop
[每 tickTime 周期]
如果在 syncLimit×tickTime 内
未收到响应,判定节点宕机
PING 心跳请求
检查自身状态
PING 心跳响应
心跳机制确保 Leader 能及时发现故障节点。超时时间由 syncLimit × tickTime 计算得出 。
4.2 事务提案的完整通信流程
其他 Follower
Leader
Follower
客户端
其他 Follower
Leader
Follower
客户端
#mermaid-svg-KQSP2JqMpfNhvE9q{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KQSP2JqMpfNhvE9q .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KQSP2JqMpfNhvE9q .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KQSP2JqMpfNhvE9q .error-icon{fill:#552222;}#mermaid-svg-KQSP2JqMpfNhvE9q .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KQSP2JqMpfNhvE9q .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KQSP2JqMpfNhvE9q .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KQSP2JqMpfNhvE9q .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KQSP2JqMpfNhvE9q .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KQSP2JqMpfNhvE9q .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KQSP2JqMpfNhvE9q .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KQSP2JqMpfNhvE9q .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KQSP2JqMpfNhvE9q .marker.cross{stroke:#333333;}#mermaid-svg-KQSP2JqMpfNhvE9q svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KQSP2JqMpfNhvE9q p{margin:0;}#mermaid-svg-KQSP2JqMpfNhvE9q .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KQSP2JqMpfNhvE9q text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-KQSP2JqMpfNhvE9q .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-KQSP2JqMpfNhvE9q .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-KQSP2JqMpfNhvE9q .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-KQSP2JqMpfNhvE9q .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-KQSP2JqMpfNhvE9q #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-KQSP2JqMpfNhvE9q .sequenceNumber{fill:white;}#mermaid-svg-KQSP2JqMpfNhvE9q #sequencenumber{fill:#333;}#mermaid-svg-KQSP2JqMpfNhvE9q #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-KQSP2JqMpfNhvE9q .messageText{fill:#333;stroke:none;}#mermaid-svg-KQSP2JqMpfNhvE9q .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KQSP2JqMpfNhvE9q .labelText,#mermaid-svg-KQSP2JqMpfNhvE9q .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-KQSP2JqMpfNhvE9q .loopText,#mermaid-svg-KQSP2JqMpfNhvE9q .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-KQSP2JqMpfNhvE9q .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-KQSP2JqMpfNhvE9q .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-KQSP2JqMpfNhvE9q .noteText,#mermaid-svg-KQSP2JqMpfNhvE9q .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-KQSP2JqMpfNhvE9q .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KQSP2JqMpfNhvE9q .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KQSP2JqMpfNhvE9q .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KQSP2JqMpfNhvE9q .actorPopupMenu{position:absolute;}#mermaid-svg-KQSP2JqMpfNhvE9q .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-KQSP2JqMpfNhvE9q .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KQSP2JqMpfNhvE9q .actor-man circle,#mermaid-svg-KQSP2JqMpfNhvE9q line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-KQSP2JqMpfNhvE9q :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
7. 收到过半 ACK
1. 写请求
2. 转发写请求
3. 生成 PROPOSAL,分配 ZXID
4. PROPOSAL(ZXID)
4. PROPOSAL(ZXID)
5. 写入事务日志
5. 写入事务日志
6. ACK
6. ACK
8. COMMIT
8. COMMIT
9. 返回结果
10. 返回成功
这个流程类似于两阶段提交,但做了优化:一旦收到过半 ACK,Leader 就可以提交,无需等待所有 Follower 。
五、Leader 选举时的通信
5.1 选举通信端口(3888)的作用
当集群启动或 Leader 故障时,所有节点进入 LOOKING 状态,通过选举端口(3888)进行通信 。
节点3 (LOOKING)
节点2 (LOOKING)
节点1 (LOOKING)
节点3 (LOOKING)
节点2 (LOOKING)
节点1 (LOOKING)
#mermaid-svg-L1eJVYZLdFbHRL8u{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-L1eJVYZLdFbHRL8u .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-L1eJVYZLdFbHRL8u .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-L1eJVYZLdFbHRL8u .error-icon{fill:#552222;}#mermaid-svg-L1eJVYZLdFbHRL8u .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-L1eJVYZLdFbHRL8u .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-L1eJVYZLdFbHRL8u .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-L1eJVYZLdFbHRL8u .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-L1eJVYZLdFbHRL8u .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-L1eJVYZLdFbHRL8u .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-L1eJVYZLdFbHRL8u .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-L1eJVYZLdFbHRL8u .marker{fill:#333333;stroke:#333333;}#mermaid-svg-L1eJVYZLdFbHRL8u .marker.cross{stroke:#333333;}#mermaid-svg-L1eJVYZLdFbHRL8u svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-L1eJVYZLdFbHRL8u p{margin:0;}#mermaid-svg-L1eJVYZLdFbHRL8u .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-L1eJVYZLdFbHRL8u text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-L1eJVYZLdFbHRL8u .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-L1eJVYZLdFbHRL8u .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-L1eJVYZLdFbHRL8u .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-L1eJVYZLdFbHRL8u .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-L1eJVYZLdFbHRL8u #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-L1eJVYZLdFbHRL8u .sequenceNumber{fill:white;}#mermaid-svg-L1eJVYZLdFbHRL8u #sequencenumber{fill:#333;}#mermaid-svg-L1eJVYZLdFbHRL8u #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-L1eJVYZLdFbHRL8u .messageText{fill:#333;stroke:none;}#mermaid-svg-L1eJVYZLdFbHRL8u .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-L1eJVYZLdFbHRL8u .labelText,#mermaid-svg-L1eJVYZLdFbHRL8u .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-L1eJVYZLdFbHRL8u .loopText,#mermaid-svg-L1eJVYZLdFbHRL8u .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-L1eJVYZLdFbHRL8u .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-L1eJVYZLdFbHRL8u .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-L1eJVYZLdFbHRL8u .noteText,#mermaid-svg-L1eJVYZLdFbHRL8u .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-L1eJVYZLdFbHRL8u .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-L1eJVYZLdFbHRL8u .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-L1eJVYZLdFbHRL8u .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-L1eJVYZLdFbHRL8u .actorPopupMenu{position:absolute;}#mermaid-svg-L1eJVYZLdFbHRL8u .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-L1eJVYZLdFbHRL8u .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-L1eJVYZLdFbHRL8u .actor-man circle,#mermaid-svg-L1eJVYZLdFbHRL8u line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-L1eJVYZLdFbHRL8u :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
比较投票规则:
1. 优先比较 lastZxid
2. 相同时比较 myid
3888 投票(1, lastZxid)
3888 投票(1, lastZxid)
3888 投票(2, lastZxid)
3888 投票(2, lastZxid)
3888 投票(3, lastZxid)
3888 投票(3, lastZxid)
获得多数票,成为 Leader
3888 通知选举结果
3888 通知选举结果
选举通信的特点:
- 采用 FastLeaderElection 算法
- 所有节点之间全互联,每个节点都与其他节点建立 TCP 连接
- 投票信息包括 (myid, lastZxid)
- 通过比较规则确定胜出者,获得超过半数的投票即可当选
5.2 选举完成后的数据同步
选举出新的 Leader 后,通信切回到 2888 端口进行数据同步:
六、Observer 节点的特殊通信
Observer 是 ZooKeeper 3.3.0+ 引入的角色,其通信方式与 Follower 略有不同 。
6.1 Observer 的通信特点
| 参与投票 | 不参与 | 参与 |
| 数据同步 | 异步同步 | 同步同步 |
| ACK 发送 | 不需要 ACK | 必须 ACK |
| 对写性能影响 | 无影响 | 有影响(需要等待 ACK) |
Follower
Observer
Leader
Follower
Observer
Leader
#mermaid-svg-phiMh4Xfx6e04XuX{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-phiMh4Xfx6e04XuX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-phiMh4Xfx6e04XuX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-phiMh4Xfx6e04XuX .error-icon{fill:#552222;}#mermaid-svg-phiMh4Xfx6e04XuX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-phiMh4Xfx6e04XuX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-phiMh4Xfx6e04XuX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-phiMh4Xfx6e04XuX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-phiMh4Xfx6e04XuX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-phiMh4Xfx6e04XuX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-phiMh4Xfx6e04XuX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-phiMh4Xfx6e04XuX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-phiMh4Xfx6e04XuX .marker.cross{stroke:#333333;}#mermaid-svg-phiMh4Xfx6e04XuX svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-phiMh4Xfx6e04XuX p{margin:0;}#mermaid-svg-phiMh4Xfx6e04XuX .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-phiMh4Xfx6e04XuX text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-phiMh4Xfx6e04XuX .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-phiMh4Xfx6e04XuX .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-phiMh4Xfx6e04XuX .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-phiMh4Xfx6e04XuX .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-phiMh4Xfx6e04XuX #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-phiMh4Xfx6e04XuX .sequenceNumber{fill:white;}#mermaid-svg-phiMh4Xfx6e04XuX #sequencenumber{fill:#333;}#mermaid-svg-phiMh4Xfx6e04XuX #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-phiMh4Xfx6e04XuX .messageText{fill:#333;stroke:none;}#mermaid-svg-phiMh4Xfx6e04XuX .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-phiMh4Xfx6e04XuX .labelText,#mermaid-svg-phiMh4Xfx6e04XuX .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-phiMh4Xfx6e04XuX .loopText,#mermaid-svg-phiMh4Xfx6e04XuX .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-phiMh4Xfx6e04XuX .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-phiMh4Xfx6e04XuX .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-phiMh4Xfx6e04XuX .noteText,#mermaid-svg-phiMh4Xfx6e04XuX .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-phiMh4Xfx6e04XuX .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-phiMh4Xfx6e04XuX .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-phiMh4Xfx6e04XuX .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-phiMh4Xfx6e04XuX .actorPopupMenu{position:absolute;}#mermaid-svg-phiMh4Xfx6e04XuX .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-phiMh4Xfx6e04XuX .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-phiMh4Xfx6e04XuX .actor-man circle,#mermaid-svg-phiMh4Xfx6e04XuX line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-phiMh4Xfx6e04XuX :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
只需等待 Follower 的 ACK
Observer 只同步数据,不参与投票
数据同步(异步)
数据同步(同步)
ACK(必须)
无需 ACK
6.2 Observer 的配置
在配置文件中,需要在节点定义后加上 :observer 标记 :
server.1=192.168.1.10:2888:3888
server.2=192.168.1.11:2888:3888
server.3=192.168.1.12:2888:3888
server.4=192.168.1.13:2888:3888:observer # Observer 节点
七、通信中的关键数据结构
7.1 ZXID:全局有序的事务标识
ZXID 是 ZooKeeper 通信中最重要的元数据,它是一个 64 位数字 :
// ZXID 结构
// 高32位:epoch(纪元)—— Leader 任期
// 低32位:counter(计数器)—— 事务序号
public class Zxid {
private long epoch; // 高32位
private long counter; // 低32位
// 示例:0x100000001 表示 epoch=1, counter=1
}
在通信过程中,节点通过交换 ZXID 来确定数据的新旧程度,用于选举和数据同步 。
7.2 LearnerHandler:处理对端连接的组件
在 Leader 端,每个连接的 Follower 都由一个 LearnerHandler 线程负责处理 :
// 简化示意
public class LearnerHandler {
private Socket socket; // 与 Follower 的 TCP 连接
private LinkedBlockingQueue<QuorumPacket> queuedPackets; // FIFO 队列
public void queuePacket(QuorumPacket p) {
queuedPackets.offer(p); // 按顺序放入队列
}
public void run() {
while (running) {
QuorumPacket p = queuedPackets.take(); // 按 FIFO 顺序取出
sendPacket(p); // 发送给 Follower
}
}
}
每个 Follower 都有独立的 FIFO 队列,确保消息按顺序发送 。
八、通信故障处理
8.1 连接断开处理
当服务器之间的 TCP 连接断开时,ZooKeeper 会采取以下措施:
| Follower 断开 | Leader 将其从可用列表中移除,不再等待其 ACK |
| Leader 断开 | Follower 检测到连接断开,进入 LOOKING 状态,发起选举 |
| 网络分区 | 少数派节点无法收到 Leader 心跳,进入 LOOKING 状态 |
8.2 超时配置
# zoo.cfg 中的超时配置
tickTime=2000 # 基本时间单位(毫秒)
initLimit=10 # 初始化同步超时(10 × tickTime = 20秒)
syncLimit=5 # 心跳超时(5 × tickTime = 10秒)
这些配置直接影响通信故障的检测速度 。
九、总结
9.1 通信要点回顾
| 传输层 | 基于 TCP 长连接,利用 FIFO 特性保证顺序 |
| 核心端口 | 2888(数据同步)、3888(选举通信) |
| 核心协议 | ZAB 原子广播协议 |
| 消息类型 | PROPOSAL、ACK、COMMIT、PING、FOLLOWERINFO 等 |
| 顺序保证 | 每个 Follower 独立 FIFO 队列 + TCP 顺序交付 |
| 故障检测 | 心跳机制 + 超时配置 |
9.2 通信流程全景图
#mermaid-svg-Se7VlKS5ji9RUkp0{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Se7VlKS5ji9RUkp0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Se7VlKS5ji9RUkp0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Se7VlKS5ji9RUkp0 .error-icon{fill:#552222;}#mermaid-svg-Se7VlKS5ji9RUkp0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Se7VlKS5ji9RUkp0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Se7VlKS5ji9RUkp0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Se7VlKS5ji9RUkp0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Se7VlKS5ji9RUkp0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Se7VlKS5ji9RUkp0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Se7VlKS5ji9RUkp0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Se7VlKS5ji9RUkp0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Se7VlKS5ji9RUkp0 .marker.cross{stroke:#333333;}#mermaid-svg-Se7VlKS5ji9RUkp0 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Se7VlKS5ji9RUkp0 p{margin:0;}#mermaid-svg-Se7VlKS5ji9RUkp0 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Se7VlKS5ji9RUkp0 .cluster-label text{fill:#333;}#mermaid-svg-Se7VlKS5ji9RUkp0 .cluster-label span{color:#333;}#mermaid-svg-Se7VlKS5ji9RUkp0 .cluster-label span p{background-color:transparent;}#mermaid-svg-Se7VlKS5ji9RUkp0 .label text,#mermaid-svg-Se7VlKS5ji9RUkp0 span{fill:#333;color:#333;}#mermaid-svg-Se7VlKS5ji9RUkp0 .node rect,#mermaid-svg-Se7VlKS5ji9RUkp0 .node circle,#mermaid-svg-Se7VlKS5ji9RUkp0 .node ellipse,#mermaid-svg-Se7VlKS5ji9RUkp0 .node polygon,#mermaid-svg-Se7VlKS5ji9RUkp0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Se7VlKS5ji9RUkp0 .rough-node .label text,#mermaid-svg-Se7VlKS5ji9RUkp0 .node .label text,#mermaid-svg-Se7VlKS5ji9RUkp0 .image-shape .label,#mermaid-svg-Se7VlKS5ji9RUkp0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-Se7VlKS5ji9RUkp0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Se7VlKS5ji9RUkp0 .rough-node .label,#mermaid-svg-Se7VlKS5ji9RUkp0 .node .label,#mermaid-svg-Se7VlKS5ji9RUkp0 .image-shape .label,#mermaid-svg-Se7VlKS5ji9RUkp0 .icon-shape .label{text-align:center;}#mermaid-svg-Se7VlKS5ji9RUkp0 .node.clickable{cursor:pointer;}#mermaid-svg-Se7VlKS5ji9RUkp0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Se7VlKS5ji9RUkp0 .arrowheadPath{fill:#333333;}#mermaid-svg-Se7VlKS5ji9RUkp0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Se7VlKS5ji9RUkp0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Se7VlKS5ji9RUkp0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Se7VlKS5ji9RUkp0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Se7VlKS5ji9RUkp0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Se7VlKS5ji9RUkp0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Se7VlKS5ji9RUkp0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Se7VlKS5ji9RUkp0 .cluster text{fill:#333;}#mermaid-svg-Se7VlKS5ji9RUkp0 .cluster span{color:#333;}#mermaid-svg-Se7VlKS5ji9RUkp0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Se7VlKS5ji9RUkp0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Se7VlKS5ji9RUkp0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-Se7VlKS5ji9RUkp0 .icon-shape,#mermaid-svg-Se7VlKS5ji9RUkp0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Se7VlKS5ji9RUkp0 .icon-shape p,#mermaid-svg-Se7VlKS5ji9RUkp0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Se7VlKS5ji9RUkp0 .icon-shape rect,#mermaid-svg-Se7VlKS5ji9RUkp0 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Se7VlKS5ji9RUkp0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Se7VlKS5ji9RUkp0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Se7VlKS5ji9RUkp0 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Observer 通信
Observer 连接 Leader
异步数据同步
不参与投票
Leader 选举时
Leader 故障
节点间 3888 端口通信
交换投票信息
选出新 Leader
新 Leader 建立 2888 连接
数据同步
正常运行时
Follower 连接 Leader 2888端口
建立 LearnerHandler
心跳检测
事务提案与提交
9.3 一句话总结
ZooKeeper 集群通过 2888 端口进行数据同步、3888 端口进行选举通信,基于 TCP 的 FIFO 特性和 ZAB 协议,构建了一套高效、可靠、有序的内部通信机制,确保了分布式协调服务的数据一致性和高可用性。

|
🌺The End🌺点点关注,收藏不迷路🌺 |






