ZooKeeper 数据一致性与可靠性保障机制深度解析
-
- 一、一致性保证:强一致性模型
-
- 1.1 ZAB协议:一致性核心
- 1.2 消息广播模式:原子性和顺序性
- 1.3 崩溃恢复模式:一致性的恢复
- 二、过半机制:可用性与一致性的平衡
-
- 2.1 过半机制的原理
- 2.2 为什么需要过半?
- 2.3 写操作流程中的过半确认
- 三、版本控制:乐观锁机制
-
- 3.1 版本号的作用
- 3.2 乐观锁的实现
- 四、会话机制:临时节点的可靠性
-
- 4.1 会话与会话超时
- 4.2 会话过期处理
- 五、持久化存储:数据的可靠性
-
- 5.1 存储架构
- 5.2 事务日志:持久化保障
- 5.3 数据快照:恢复加速
- 六、数据同步:集群一致性保障
-
- 6.1 启动时的数据恢复
- 6.2 崩溃后的数据同步
- 6.3 读请求的一致性
- 七、ACL权限:安全可靠性
-
- 7.1 ACL组成
- 7.2 权限类型
- 7.3 权限的作用
- 八、监控与告警:运行可靠性
-
- 8.1 四字命令监控
- 8.2 关键监控指标
- 九、总结
-
- 9.1 一致性保障体系
- 9.2 核心设计理念
- 9.3 一句话总结
|
🌺The Begin🌺点点关注,收藏不迷路🌺 |
摘要:在分布式系统中,数据一致性和可靠性是衡量系统质量的核心指标。ZooKeeper作为分布式协调服务,通过一套精心设计的机制——ZAB协议、过半机制、版本控制、会话管理、持久化存储等——来确保数据的一致性和可靠性。本文将全面剖析这些机制的工作原理和实现方式,帮助读者深入理解ZooKeeper的可靠性设计。
一、一致性保证:强一致性模型
ZooKeeper提供的是强一致性保证(严格来说,是顺序一致性+单一系统映像)。
#mermaid-svg-QnqfXwjWID5nsgnD{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-QnqfXwjWID5nsgnD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QnqfXwjWID5nsgnD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QnqfXwjWID5nsgnD .error-icon{fill:#552222;}#mermaid-svg-QnqfXwjWID5nsgnD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QnqfXwjWID5nsgnD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QnqfXwjWID5nsgnD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QnqfXwjWID5nsgnD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QnqfXwjWID5nsgnD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QnqfXwjWID5nsgnD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QnqfXwjWID5nsgnD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QnqfXwjWID5nsgnD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QnqfXwjWID5nsgnD .marker.cross{stroke:#333333;}#mermaid-svg-QnqfXwjWID5nsgnD svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QnqfXwjWID5nsgnD p{margin:0;}#mermaid-svg-QnqfXwjWID5nsgnD .edge{stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .section–1 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section–1 path,#mermaid-svg-QnqfXwjWID5nsgnD .section–1 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section–1 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section–1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section–1 text{fill:#ffffff;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon–1{font-size:40px;color:#ffffff;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge–1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth–1{stroke-width:17;}#mermaid-svg-QnqfXwjWID5nsgnD .section–1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-0 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-0 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-0 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-0 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-0 text{fill:black;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-0{font-size:40px;color:black;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-0{stroke-width:14;}#mermaid-svg-QnqfXwjWID5nsgnD .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-1 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-1 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-1 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-1 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-1 text{fill:black;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-1{font-size:40px;color:black;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-1{stroke-width:11;}#mermaid-svg-QnqfXwjWID5nsgnD .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-2 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-2 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-2 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-2 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-2 text{fill:#ffffff;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-2{stroke-width:8;}#mermaid-svg-QnqfXwjWID5nsgnD .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-3 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-3 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-3 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-3 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-3 text{fill:black;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-3{font-size:40px;color:black;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-3{stroke-width:5;}#mermaid-svg-QnqfXwjWID5nsgnD .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-4 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-4 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-4 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-4 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-4 text{fill:black;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-4{font-size:40px;color:black;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-4{stroke-width:2;}#mermaid-svg-QnqfXwjWID5nsgnD .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-5 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-5 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-5 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-5 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-5 text{fill:black;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-5{font-size:40px;color:black;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-5{stroke-width:-1;}#mermaid-svg-QnqfXwjWID5nsgnD .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-6 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-6 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-6 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-6 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-6 text{fill:black;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-6{font-size:40px;color:black;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-6{stroke-width:-4;}#mermaid-svg-QnqfXwjWID5nsgnD .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-7 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-7 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-7 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-7 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-7 text{fill:black;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-7{font-size:40px;color:black;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-7{stroke-width:-7;}#mermaid-svg-QnqfXwjWID5nsgnD .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-8 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-8 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-8 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-8 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-8 text{fill:black;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-8{font-size:40px;color:black;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-8{stroke-width:-10;}#mermaid-svg-QnqfXwjWID5nsgnD .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-9 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-9 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-9 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-9 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-9 text{fill:black;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-9{font-size:40px;color:black;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-9{stroke-width:-13;}#mermaid-svg-QnqfXwjWID5nsgnD .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-10 rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-10 path,#mermaid-svg-QnqfXwjWID5nsgnD .section-10 circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-10 polygon,#mermaid-svg-QnqfXwjWID5nsgnD .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-10 text{fill:black;}#mermaid-svg-QnqfXwjWID5nsgnD .node-icon-10{font-size:40px;color:black;}#mermaid-svg-QnqfXwjWID5nsgnD .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .edge-depth-10{stroke-width:-16;}#mermaid-svg-QnqfXwjWID5nsgnD .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled,#mermaid-svg-QnqfXwjWID5nsgnD .disabled circle,#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:lightgray;}#mermaid-svg-QnqfXwjWID5nsgnD .disabled text{fill:#efefef;}#mermaid-svg-QnqfXwjWID5nsgnD .section-root rect,#mermaid-svg-QnqfXwjWID5nsgnD .section-root path,#mermaid-svg-QnqfXwjWID5nsgnD .section-root circle,#mermaid-svg-QnqfXwjWID5nsgnD .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-QnqfXwjWID5nsgnD .section-root text{fill:#ffffff;}#mermaid-svg-QnqfXwjWID5nsgnD .section-root span{color:#ffffff;}#mermaid-svg-QnqfXwjWID5nsgnD .section-2 span{color:#ffffff;}#mermaid-svg-QnqfXwjWID5nsgnD .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-QnqfXwjWID5nsgnD .edge{fill:none;}#mermaid-svg-QnqfXwjWID5nsgnD .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-QnqfXwjWID5nsgnD :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
一致性保证
ZAB协议
原子广播
崩溃恢复
过半机制
多数派确认
容错能力
顺序一致性
ZXID全局有序
操作顺序保证
单一系统映像
客户端视角一致性
Sync命令保证
1.1 ZAB协议:一致性核心
ZAB(ZooKeeper Atomic Broadcast)协议是ZooKeeper保证数据一致性的核心机制。它将集群分为两种模式:
| 消息广播 | 正常运行时处理写请求 | 所有节点按相同顺序执行事务 |
| 崩溃恢复 | Leader故障时恢复 | 确保数据不丢失、不冲突 |
1.2 消息广播模式:原子性和顺序性
Follower3
Follower2
Follower1
Leader
客户端
Follower3
Follower2
Follower1
Leader
客户端
#mermaid-svg-0pZYigGbwZO9Ngpx{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-0pZYigGbwZO9Ngpx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0pZYigGbwZO9Ngpx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0pZYigGbwZO9Ngpx .error-icon{fill:#552222;}#mermaid-svg-0pZYigGbwZO9Ngpx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0pZYigGbwZO9Ngpx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0pZYigGbwZO9Ngpx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0pZYigGbwZO9Ngpx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0pZYigGbwZO9Ngpx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0pZYigGbwZO9Ngpx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0pZYigGbwZO9Ngpx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0pZYigGbwZO9Ngpx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0pZYigGbwZO9Ngpx .marker.cross{stroke:#333333;}#mermaid-svg-0pZYigGbwZO9Ngpx svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0pZYigGbwZO9Ngpx p{margin:0;}#mermaid-svg-0pZYigGbwZO9Ngpx .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-0pZYigGbwZO9Ngpx text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-0pZYigGbwZO9Ngpx .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-0pZYigGbwZO9Ngpx .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-0pZYigGbwZO9Ngpx .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-0pZYigGbwZO9Ngpx .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-0pZYigGbwZO9Ngpx #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-0pZYigGbwZO9Ngpx .sequenceNumber{fill:white;}#mermaid-svg-0pZYigGbwZO9Ngpx #sequencenumber{fill:#333;}#mermaid-svg-0pZYigGbwZO9Ngpx #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-0pZYigGbwZO9Ngpx .messageText{fill:#333;stroke:none;}#mermaid-svg-0pZYigGbwZO9Ngpx .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-0pZYigGbwZO9Ngpx .labelText,#mermaid-svg-0pZYigGbwZO9Ngpx .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-0pZYigGbwZO9Ngpx .loopText,#mermaid-svg-0pZYigGbwZO9Ngpx .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-0pZYigGbwZO9Ngpx .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-0pZYigGbwZO9Ngpx .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-0pZYigGbwZO9Ngpx .noteText,#mermaid-svg-0pZYigGbwZO9Ngpx .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-0pZYigGbwZO9Ngpx .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-0pZYigGbwZO9Ngpx .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-0pZYigGbwZO9Ngpx .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-0pZYigGbwZO9Ngpx .actorPopupMenu{position:absolute;}#mermaid-svg-0pZYigGbwZO9Ngpx .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-0pZYigGbwZO9Ngpx .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-0pZYigGbwZO9Ngpx .actor-man circle,#mermaid-svg-0pZYigGbwZO9Ngpx line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-0pZYigGbwZO9Ngpx :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
收到过半ACK
写请求
生成Proposal,分配ZXID
PROPOSAL(ZXID)
PROPOSAL(ZXID)
PROPOSAL(ZXID)
ACK
ACK
COMMIT
COMMIT
COMMIT
成功响应
原子性保证:要么所有Follower都提交事务,要么都不提交。通过两阶段提交变种实现。
顺序性保证:Leader为每个事务分配全局递增的ZXID,Follower严格按照ZXID顺序执行。
1.3 崩溃恢复模式:一致性的恢复
当Leader故障时,ZAB协议进入崩溃恢复模式:
#mermaid-svg-0ioj4vqYRSKgVCFF{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-0ioj4vqYRSKgVCFF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0ioj4vqYRSKgVCFF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0ioj4vqYRSKgVCFF .error-icon{fill:#552222;}#mermaid-svg-0ioj4vqYRSKgVCFF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0ioj4vqYRSKgVCFF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0ioj4vqYRSKgVCFF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0ioj4vqYRSKgVCFF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0ioj4vqYRSKgVCFF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0ioj4vqYRSKgVCFF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0ioj4vqYRSKgVCFF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0ioj4vqYRSKgVCFF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0ioj4vqYRSKgVCFF .marker.cross{stroke:#333333;}#mermaid-svg-0ioj4vqYRSKgVCFF svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0ioj4vqYRSKgVCFF p{margin:0;}#mermaid-svg-0ioj4vqYRSKgVCFF .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-0ioj4vqYRSKgVCFF .cluster-label text{fill:#333;}#mermaid-svg-0ioj4vqYRSKgVCFF .cluster-label span{color:#333;}#mermaid-svg-0ioj4vqYRSKgVCFF .cluster-label span p{background-color:transparent;}#mermaid-svg-0ioj4vqYRSKgVCFF .label text,#mermaid-svg-0ioj4vqYRSKgVCFF span{fill:#333;color:#333;}#mermaid-svg-0ioj4vqYRSKgVCFF .node rect,#mermaid-svg-0ioj4vqYRSKgVCFF .node circle,#mermaid-svg-0ioj4vqYRSKgVCFF .node ellipse,#mermaid-svg-0ioj4vqYRSKgVCFF .node polygon,#mermaid-svg-0ioj4vqYRSKgVCFF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0ioj4vqYRSKgVCFF .rough-node .label text,#mermaid-svg-0ioj4vqYRSKgVCFF .node .label text,#mermaid-svg-0ioj4vqYRSKgVCFF .image-shape .label,#mermaid-svg-0ioj4vqYRSKgVCFF .icon-shape .label{text-anchor:middle;}#mermaid-svg-0ioj4vqYRSKgVCFF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0ioj4vqYRSKgVCFF .rough-node .label,#mermaid-svg-0ioj4vqYRSKgVCFF .node .label,#mermaid-svg-0ioj4vqYRSKgVCFF .image-shape .label,#mermaid-svg-0ioj4vqYRSKgVCFF .icon-shape .label{text-align:center;}#mermaid-svg-0ioj4vqYRSKgVCFF .node.clickable{cursor:pointer;}#mermaid-svg-0ioj4vqYRSKgVCFF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0ioj4vqYRSKgVCFF .arrowheadPath{fill:#333333;}#mermaid-svg-0ioj4vqYRSKgVCFF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0ioj4vqYRSKgVCFF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0ioj4vqYRSKgVCFF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0ioj4vqYRSKgVCFF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0ioj4vqYRSKgVCFF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0ioj4vqYRSKgVCFF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0ioj4vqYRSKgVCFF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0ioj4vqYRSKgVCFF .cluster text{fill:#333;}#mermaid-svg-0ioj4vqYRSKgVCFF .cluster span{color:#333;}#mermaid-svg-0ioj4vqYRSKgVCFF 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-0ioj4vqYRSKgVCFF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0ioj4vqYRSKgVCFF rect.text{fill:none;stroke-width:0;}#mermaid-svg-0ioj4vqYRSKgVCFF .icon-shape,#mermaid-svg-0ioj4vqYRSKgVCFF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0ioj4vqYRSKgVCFF .icon-shape p,#mermaid-svg-0ioj4vqYRSKgVCFF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0ioj4vqYRSKgVCFF .icon-shape rect,#mermaid-svg-0ioj4vqYRSKgVCFF .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0ioj4vqYRSKgVCFF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0ioj4vqYRSKgVCFF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0ioj4vqYRSKgVCFF :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
DIFF
TRUNC
SNAP
Leader故障
Leader选举
数据同步
增量同步
回滚多余事务
全量同步
集群恢复服务
关键设计:新Leader必须拥有集群中最新的数据(ZXID最大),确保不会丢失已提交事务。
二、过半机制:可用性与一致性的平衡
2.1 过半机制的原理
ZooKeeper的所有决策(写提交、Leader选举)都需要超过半数节点的同意。
| 3台 | 2台 | 1台 |
| 5台 | 3台 | 2台 |
| 7台 | 4台 | 3台 |
// 过半机制的核心公式
int majority = totalNodes / 2 + 1;
2.2 为什么需要过半?
过半机制保证了两个重要性质:
2.3 写操作流程中的过半确认
// 写操作的过半确认过程
public class WriteProcess {
// 1. Leader广播提案
// 2. 等待Follower的ACK
// 3. 收到过半ACK后提交
// 4. 响应客户端
// 如果少数Follower故障,不影响写操作
// 如果多数Follower故障,写操作失败
}
三、版本控制:乐观锁机制
3.1 版本号的作用
ZooKeeper为每个ZNode维护三个版本号,用于实现乐观锁:
| dataVersion | 数据版本 | 每次set操作+1 |
| cversion | 子节点版本 | 子节点新增/删除+1 |
| aversion | ACL版本 | 每次setAcl操作+1 |
3.2 乐观锁的实现
public class OptimisticLockExample {
public boolean updateWithVersion(String path, String newData) throws Exception {
// 1. 获取当前数据和版本号
Stat stat = new Stat();
byte[] data = zk.getData(path, false, stat);
int currentVersion = stat.getVersion();
// 2. 业务处理
String processed = processData(new String(data), newData);
try {
// 3. 使用版本号更新(版本必须匹配)
zk.setData(path, processed.getBytes(), currentVersion);
return true;
} catch (KeeperException.BadVersionException e) {
// 4. 版本冲突,重试
return false;
}
}
}
版本控制的威力:
- 防止并发修改导致的数据覆盖
- 实现CAS(Compare-And-Swap)操作
- 保证数据修改的原子性
四、会话机制:临时节点的可靠性
4.1 会话与会话超时
每个客户端连接对应一个会话(Session),服务端为每个会话维护:
| sessionId | 全局唯一会话标识 |
| timeout | 会话超时时间 |
| 临时节点列表 | 该会话创建的所有临时节点 |
4.2 会话过期处理
ZooKeeper
客户端
ZooKeeper
客户端
#mermaid-svg-NCO8EakQZ2hyJlzZ{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-NCO8EakQZ2hyJlzZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NCO8EakQZ2hyJlzZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NCO8EakQZ2hyJlzZ .error-icon{fill:#552222;}#mermaid-svg-NCO8EakQZ2hyJlzZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NCO8EakQZ2hyJlzZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NCO8EakQZ2hyJlzZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NCO8EakQZ2hyJlzZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NCO8EakQZ2hyJlzZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NCO8EakQZ2hyJlzZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NCO8EakQZ2hyJlzZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NCO8EakQZ2hyJlzZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NCO8EakQZ2hyJlzZ .marker.cross{stroke:#333333;}#mermaid-svg-NCO8EakQZ2hyJlzZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NCO8EakQZ2hyJlzZ p{margin:0;}#mermaid-svg-NCO8EakQZ2hyJlzZ .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-NCO8EakQZ2hyJlzZ text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-NCO8EakQZ2hyJlzZ .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-NCO8EakQZ2hyJlzZ .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-NCO8EakQZ2hyJlzZ .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-NCO8EakQZ2hyJlzZ .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-NCO8EakQZ2hyJlzZ #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-NCO8EakQZ2hyJlzZ .sequenceNumber{fill:white;}#mermaid-svg-NCO8EakQZ2hyJlzZ #sequencenumber{fill:#333;}#mermaid-svg-NCO8EakQZ2hyJlzZ #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-NCO8EakQZ2hyJlzZ .messageText{fill:#333;stroke:none;}#mermaid-svg-NCO8EakQZ2hyJlzZ .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-NCO8EakQZ2hyJlzZ .labelText,#mermaid-svg-NCO8EakQZ2hyJlzZ .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-NCO8EakQZ2hyJlzZ .loopText,#mermaid-svg-NCO8EakQZ2hyJlzZ .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-NCO8EakQZ2hyJlzZ .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-NCO8EakQZ2hyJlzZ .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-NCO8EakQZ2hyJlzZ .noteText,#mermaid-svg-NCO8EakQZ2hyJlzZ .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-NCO8EakQZ2hyJlzZ .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-NCO8EakQZ2hyJlzZ .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-NCO8EakQZ2hyJlzZ .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-NCO8EakQZ2hyJlzZ .actorPopupMenu{position:absolute;}#mermaid-svg-NCO8EakQZ2hyJlzZ .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-NCO8EakQZ2hyJlzZ .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-NCO8EakQZ2hyJlzZ .actor-man circle,#mermaid-svg-NCO8EakQZ2hyJlzZ line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-NCO8EakQZ2hyJlzZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
网络断开
临时节点保留
alt
[超时前重连成功]
[超过超时时间]
创建临时节点 /temp
记录会话->>节点映射
启动会话超时计时器
尝试重连
重新连接,携带sessionId
取消超时计时
清理该会话的所有临时节点
重连时创建新会话
会话机制的价值:
- 临时节点自动清理,避免僵尸节点
- 会话超时容错网络抖动
- 会话跟踪客户端状态
五、持久化存储:数据的可靠性
5.1 存储架构
ZooKeeper采用内存数据库 + 磁盘日志的存储架构:
#mermaid-svg-WOkKui2TapHqzLfe{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-WOkKui2TapHqzLfe .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WOkKui2TapHqzLfe .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WOkKui2TapHqzLfe .error-icon{fill:#552222;}#mermaid-svg-WOkKui2TapHqzLfe .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WOkKui2TapHqzLfe .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WOkKui2TapHqzLfe .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WOkKui2TapHqzLfe .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WOkKui2TapHqzLfe .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WOkKui2TapHqzLfe .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WOkKui2TapHqzLfe .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WOkKui2TapHqzLfe .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WOkKui2TapHqzLfe .marker.cross{stroke:#333333;}#mermaid-svg-WOkKui2TapHqzLfe svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WOkKui2TapHqzLfe p{margin:0;}#mermaid-svg-WOkKui2TapHqzLfe .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-WOkKui2TapHqzLfe .cluster-label text{fill:#333;}#mermaid-svg-WOkKui2TapHqzLfe .cluster-label span{color:#333;}#mermaid-svg-WOkKui2TapHqzLfe .cluster-label span p{background-color:transparent;}#mermaid-svg-WOkKui2TapHqzLfe .label text,#mermaid-svg-WOkKui2TapHqzLfe span{fill:#333;color:#333;}#mermaid-svg-WOkKui2TapHqzLfe .node rect,#mermaid-svg-WOkKui2TapHqzLfe .node circle,#mermaid-svg-WOkKui2TapHqzLfe .node ellipse,#mermaid-svg-WOkKui2TapHqzLfe .node polygon,#mermaid-svg-WOkKui2TapHqzLfe .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WOkKui2TapHqzLfe .rough-node .label text,#mermaid-svg-WOkKui2TapHqzLfe .node .label text,#mermaid-svg-WOkKui2TapHqzLfe .image-shape .label,#mermaid-svg-WOkKui2TapHqzLfe .icon-shape .label{text-anchor:middle;}#mermaid-svg-WOkKui2TapHqzLfe .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WOkKui2TapHqzLfe .rough-node .label,#mermaid-svg-WOkKui2TapHqzLfe .node .label,#mermaid-svg-WOkKui2TapHqzLfe .image-shape .label,#mermaid-svg-WOkKui2TapHqzLfe .icon-shape .label{text-align:center;}#mermaid-svg-WOkKui2TapHqzLfe .node.clickable{cursor:pointer;}#mermaid-svg-WOkKui2TapHqzLfe .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WOkKui2TapHqzLfe .arrowheadPath{fill:#333333;}#mermaid-svg-WOkKui2TapHqzLfe .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WOkKui2TapHqzLfe .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WOkKui2TapHqzLfe .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WOkKui2TapHqzLfe .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WOkKui2TapHqzLfe .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WOkKui2TapHqzLfe .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WOkKui2TapHqzLfe .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WOkKui2TapHqzLfe .cluster text{fill:#333;}#mermaid-svg-WOkKui2TapHqzLfe .cluster span{color:#333;}#mermaid-svg-WOkKui2TapHqzLfe 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-WOkKui2TapHqzLfe .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WOkKui2TapHqzLfe rect.text{fill:none;stroke-width:0;}#mermaid-svg-WOkKui2TapHqzLfe .icon-shape,#mermaid-svg-WOkKui2TapHqzLfe .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WOkKui2TapHqzLfe .icon-shape p,#mermaid-svg-WOkKui2TapHqzLfe .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WOkKui2TapHqzLfe .icon-shape rect,#mermaid-svg-WOkKui2TapHqzLfe .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WOkKui2TapHqzLfe .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WOkKui2TapHqzLfe .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WOkKui2TapHqzLfe :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
磁盘
内存
定时快照
每次写操作
启动恢复
启动加载
DataTree数据树
内存数据库
事务日志transaction log
数据快照snapshot
5.2 事务日志:持久化保障
// 事务日志写入过程
public class TransactionLog {
public void logTransaction(Txn txn) {
// 1. 预分配日志文件(64MB)
// 2. 追加写入事务记录
// 3. 可配置强制刷盘(forceSync)
// 4. 记录ZXID
// 5. 文件满后滚动新文件
}
}
事务日志的作用:
- 记录所有写操作,用于故障恢复
- 保证数据不丢失
- 支持增量恢复
5.3 数据快照:恢复加速
快照触发条件:每执行snapCount次事务后触发(默认100000次)
// 快照触发逻辑(带有随机性避免同时触发)
randRoll = random(1, snapCount / 2);
if (logCount > (snapCount / 2 + randRoll)) {
takeSnapshot(); // 触发快照
}
快照的作用:
- 内存数据的全量备份
- 加快服务重启恢复速度
- 减少日志重放的工作量
六、数据同步:集群一致性保障
6.1 启动时的数据恢复
#mermaid-svg-3R3JoBhNTVMD8QcJ{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-3R3JoBhNTVMD8QcJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3R3JoBhNTVMD8QcJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3R3JoBhNTVMD8QcJ .error-icon{fill:#552222;}#mermaid-svg-3R3JoBhNTVMD8QcJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3R3JoBhNTVMD8QcJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3R3JoBhNTVMD8QcJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3R3JoBhNTVMD8QcJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3R3JoBhNTVMD8QcJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3R3JoBhNTVMD8QcJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3R3JoBhNTVMD8QcJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3R3JoBhNTVMD8QcJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3R3JoBhNTVMD8QcJ .marker.cross{stroke:#333333;}#mermaid-svg-3R3JoBhNTVMD8QcJ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3R3JoBhNTVMD8QcJ p{margin:0;}#mermaid-svg-3R3JoBhNTVMD8QcJ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-3R3JoBhNTVMD8QcJ .cluster-label text{fill:#333;}#mermaid-svg-3R3JoBhNTVMD8QcJ .cluster-label span{color:#333;}#mermaid-svg-3R3JoBhNTVMD8QcJ .cluster-label span p{background-color:transparent;}#mermaid-svg-3R3JoBhNTVMD8QcJ .label text,#mermaid-svg-3R3JoBhNTVMD8QcJ span{fill:#333;color:#333;}#mermaid-svg-3R3JoBhNTVMD8QcJ .node rect,#mermaid-svg-3R3JoBhNTVMD8QcJ .node circle,#mermaid-svg-3R3JoBhNTVMD8QcJ .node ellipse,#mermaid-svg-3R3JoBhNTVMD8QcJ .node polygon,#mermaid-svg-3R3JoBhNTVMD8QcJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3R3JoBhNTVMD8QcJ .rough-node .label text,#mermaid-svg-3R3JoBhNTVMD8QcJ .node .label text,#mermaid-svg-3R3JoBhNTVMD8QcJ .image-shape .label,#mermaid-svg-3R3JoBhNTVMD8QcJ .icon-shape .label{text-anchor:middle;}#mermaid-svg-3R3JoBhNTVMD8QcJ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3R3JoBhNTVMD8QcJ .rough-node .label,#mermaid-svg-3R3JoBhNTVMD8QcJ .node .label,#mermaid-svg-3R3JoBhNTVMD8QcJ .image-shape .label,#mermaid-svg-3R3JoBhNTVMD8QcJ .icon-shape .label{text-align:center;}#mermaid-svg-3R3JoBhNTVMD8QcJ .node.clickable{cursor:pointer;}#mermaid-svg-3R3JoBhNTVMD8QcJ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3R3JoBhNTVMD8QcJ .arrowheadPath{fill:#333333;}#mermaid-svg-3R3JoBhNTVMD8QcJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3R3JoBhNTVMD8QcJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3R3JoBhNTVMD8QcJ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3R3JoBhNTVMD8QcJ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3R3JoBhNTVMD8QcJ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3R3JoBhNTVMD8QcJ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3R3JoBhNTVMD8QcJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3R3JoBhNTVMD8QcJ .cluster text{fill:#333;}#mermaid-svg-3R3JoBhNTVMD8QcJ .cluster span{color:#333;}#mermaid-svg-3R3JoBhNTVMD8QcJ 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-3R3JoBhNTVMD8QcJ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3R3JoBhNTVMD8QcJ rect.text{fill:none;stroke-width:0;}#mermaid-svg-3R3JoBhNTVMD8QcJ .icon-shape,#mermaid-svg-3R3JoBhNTVMD8QcJ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3R3JoBhNTVMD8QcJ .icon-shape p,#mermaid-svg-3R3JoBhNTVMD8QcJ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3R3JoBhNTVMD8QcJ .icon-shape rect,#mermaid-svg-3R3JoBhNTVMD8QcJ .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3R3JoBhNTVMD8QcJ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3R3JoBhNTVMD8QcJ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3R3JoBhNTVMD8QcJ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
服务启动
加载最新快照
获取快照的zxid
重放zxid+1开始的日志
应用事务到内存
服务就绪
6.2 崩溃后的数据同步
新Leader当选后,需要与Follower进行数据同步:
| DIFF | Follower落后少量事务 | 增量发送缺失事务 |
| TRUNC | Follower有多余事务 | 回滚多余事务 |
| SNAP | Follower落后太多 | 全量发送快照 |
6.3 读请求的一致性
ZooKeeper的读请求可以发送给任意节点,这可能导致读到旧数据。如果要求强一致读:
# 方案1:发送给Leader
# 方案2:先执行sync命令
sync /path
get /path
七、ACL权限:安全可靠性
7.1 ACL组成
#mermaid-svg-yIlWLJbB0X8BCsGU{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-yIlWLJbB0X8BCsGU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yIlWLJbB0X8BCsGU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yIlWLJbB0X8BCsGU .error-icon{fill:#552222;}#mermaid-svg-yIlWLJbB0X8BCsGU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yIlWLJbB0X8BCsGU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yIlWLJbB0X8BCsGU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yIlWLJbB0X8BCsGU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yIlWLJbB0X8BCsGU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yIlWLJbB0X8BCsGU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yIlWLJbB0X8BCsGU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yIlWLJbB0X8BCsGU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yIlWLJbB0X8BCsGU .marker.cross{stroke:#333333;}#mermaid-svg-yIlWLJbB0X8BCsGU svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yIlWLJbB0X8BCsGU p{margin:0;}#mermaid-svg-yIlWLJbB0X8BCsGU .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-yIlWLJbB0X8BCsGU .cluster-label text{fill:#333;}#mermaid-svg-yIlWLJbB0X8BCsGU .cluster-label span{color:#333;}#mermaid-svg-yIlWLJbB0X8BCsGU .cluster-label span p{background-color:transparent;}#mermaid-svg-yIlWLJbB0X8BCsGU .label text,#mermaid-svg-yIlWLJbB0X8BCsGU span{fill:#333;color:#333;}#mermaid-svg-yIlWLJbB0X8BCsGU .node rect,#mermaid-svg-yIlWLJbB0X8BCsGU .node circle,#mermaid-svg-yIlWLJbB0X8BCsGU .node ellipse,#mermaid-svg-yIlWLJbB0X8BCsGU .node polygon,#mermaid-svg-yIlWLJbB0X8BCsGU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yIlWLJbB0X8BCsGU .rough-node .label text,#mermaid-svg-yIlWLJbB0X8BCsGU .node .label text,#mermaid-svg-yIlWLJbB0X8BCsGU .image-shape .label,#mermaid-svg-yIlWLJbB0X8BCsGU .icon-shape .label{text-anchor:middle;}#mermaid-svg-yIlWLJbB0X8BCsGU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yIlWLJbB0X8BCsGU .rough-node .label,#mermaid-svg-yIlWLJbB0X8BCsGU .node .label,#mermaid-svg-yIlWLJbB0X8BCsGU .image-shape .label,#mermaid-svg-yIlWLJbB0X8BCsGU .icon-shape .label{text-align:center;}#mermaid-svg-yIlWLJbB0X8BCsGU .node.clickable{cursor:pointer;}#mermaid-svg-yIlWLJbB0X8BCsGU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yIlWLJbB0X8BCsGU .arrowheadPath{fill:#333333;}#mermaid-svg-yIlWLJbB0X8BCsGU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yIlWLJbB0X8BCsGU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yIlWLJbB0X8BCsGU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yIlWLJbB0X8BCsGU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yIlWLJbB0X8BCsGU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yIlWLJbB0X8BCsGU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yIlWLJbB0X8BCsGU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yIlWLJbB0X8BCsGU .cluster text{fill:#333;}#mermaid-svg-yIlWLJbB0X8BCsGU .cluster span{color:#333;}#mermaid-svg-yIlWLJbB0X8BCsGU 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-yIlWLJbB0X8BCsGU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yIlWLJbB0X8BCsGU rect.text{fill:none;stroke-width:0;}#mermaid-svg-yIlWLJbB0X8BCsGU .icon-shape,#mermaid-svg-yIlWLJbB0X8BCsGU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yIlWLJbB0X8BCsGU .icon-shape p,#mermaid-svg-yIlWLJbB0X8BCsGU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yIlWLJbB0X8BCsGU .icon-shape rect,#mermaid-svg-yIlWLJbB0X8BCsGU .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yIlWLJbB0X8BCsGU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yIlWLJbB0X8BCsGU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yIlWLJbB0X8BCsGU :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
ACL结构
ACL
scheme: 授权方案
id: 授权ID
perms: 权限位
7.2 权限类型
| CREATE | c | 允许创建子节点 |
| DELETE | d | 允许删除子节点 |
| READ | r | 允许读取节点数据 |
| WRITE | w | 允许修改节点数据 |
| ADMIN | a | 允许设置ACL |
7.3 权限的作用
# 创建受保护的节点
addauth digest admin:admin123
create /secure-node "secret" auth:admin:admin123:cdrwa
# 无权限时无法访问
get /secure-node
KeeperErrorCode = NoAuth for /secure-node
ACL机制防止未经授权的访问,保障数据的安全性。
八、监控与告警:运行可靠性
8.1 四字命令监控
# 检查服务器状态
echo stat | nc localhost 2181
# 获取监控指标
echo mntr | nc localhost 2181
# 测试存活
echo ruok | nc localhost 2181
8.2 关键监控指标
| zk_znode_count | 稳定 | 节点数突增可能表示异常 |
| zk_watch_count | 稳定 | Watch过多可能内存溢出 |
| zk_outstanding_requests | < 100 | 请求堆积,处理慢 |
| zk_avg_latency | < 10ms | 延迟高,磁盘I/O问题 |
九、总结
9.1 一致性保障体系
| ZAB协议 | 原子性、顺序性 | 两阶段广播+崩溃恢复 |
| 过半机制 | 可用性与一致性平衡 | 多数派确认 |
| 版本控制 | 并发修改冲突 | 乐观锁 |
| 会话机制 | 临时节点生命周期 | 会话超时跟踪 |
| 持久化存储 | 数据不丢失 | 事务日志+快照 |
| 数据同步 | 集群一致性 | DIFF/TRUNC/SNAP |
| ACL权限 | 访问控制 | 权限验证 |
| 监控告警 | 运行时可靠性 | 指标采集+阈值告警 |
9.2 核心设计理念
ZooKeeper通过ZAB协议保证操作的一致性,通过过半机制平衡可用性和一致性,通过版本控制处理并发冲突,通过会话机制管理临时节点,通过持久化存储保障数据可靠性。这套完整的机制共同构成了一个高可靠、强一致的分布式协调服务。
9.3 一句话总结
ZooKeeper通过ZAB协议确保事务的一致性和顺序性,通过过半机制平衡可用性和一致性,通过版本控制防止并发冲突,通过会话机制管理临时节点生命周期,通过事务日志和快照保证数据持久化,通过数据同步维护集群一致性,最终形成一个全面保障数据一致性和可靠性的分布式系统。

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



