文章目錄
- 原理
- 選舉機制(重點)
- 情況1:正常啟動集群
- 情況2:集群啟動完,中途有機器掛了
- 監聽器
- 客戶端向服務端寫入數據
- 客戶端向服務端Leader節點寫入
- 客戶端向服務端Follower節點寫入
- Paxos算法(每個節點都可以提議者)
- ZAB協議算法 - Paxos算法的改良 - 集群僅能一位提議者(即Leader)
- 認識
- 崩潰恢復
- Leader掛,重新選舉
- 數據恢復
- CAP理倫
- 腳本
- 集群統一啟動、關閉、狀態查看腳本
- 源碼分析(粗略)
- 輔助源碼
- 持久化
- 序列化
- 服務端啟動流程
- 服務端選舉Leader流程
- Leader、Follower數據同步流程
- 服務端Leader啟動Zk過程
- 服務端Follower啟動Zk過程
- 客戶端連接Zk服務端過程
原理
選舉機制(重點)
情況1:正常啟動集群
集群正常總固定票數: conf/zoo.cfg里面的server.的配置行數
?
特點:
- 一旦選舉出領導leader,除非作為leader的zookeeper掛了,否則不會在重新選舉,其他新進的zookeeper集群都作為追隨者Following
- 存活的zookeeper機器必須【集群正常總固定票數】的一半以上才會進行選舉leader角色,否則一直是Looking
- zookeeper可以給自己投票,一旦每個人的票數都一樣,交換myid查看后,誰大就把投自己的票改投成myid最大的那個
?
集群中5臺zookeeper機器依次啟動后選舉領導的整個過程
情況2:集群啟動完,中途有機器掛了
監聽器
流程: zookeeper客戶端告知服務端需要監聽某某節點的數據變化,服務端一旦節點發生變化,就將變化通知內容推送給客戶端
?
監聽數據的變化
監聽子節點增刪的變化
客戶端向服務端寫入數據
客戶端向服務端Leader節點寫入
流程: Leader會傳遞給Follower去寫入,如果 超半數的zookeeper都寫入成功,則Leader服務端機器會告訴客戶端數據寫入成功 ,剩下Follower還未寫入的Leader會慢慢通知他們寫入,反正最終zookeeper服務端集群內所有機器都寫入成功
客戶端向服務端Follower節點寫入
流程: Follower會先將 客戶端的寫入請求轉給Leader,Leader自己將寫入請求先執行,在將這個寫入請求分發給集群內所有Follower機器 ,所有集群中超過半數的zookeeper都寫入成功,則Leader會告知當初最開始那臺Follower機器說明此次寫入成功,然后由該臺Follower告知客戶端集群此次寫入成功
Paxos算法(每個節點都可以提議者)
Paxos算法: 基于消息傳遞且具有高度容錯特性的一致性算法。快速正確的在一個分布式系統保持數據值一致,保證無論發生任何異常都不會破壞系統的一致性
?
Propose(提議): 任務編號
?
Proposal(提案): 任務編號+任務內容
?
Paxos算法完美情況
?
Paxos算法弊端
ZAB協議算法 - Paxos算法的改良 - 集群僅能一位提議者(即Leader)
認識
概念: 只有一臺客戶端(Leader)負責處理外部的寫事務請求,然后Leader客戶端將數據同步到其他Follower節點。即Zookeeper只有一個Leader可以發起提案
此圖對應的是上圖的流程圖
崩潰恢復
Leader掛,重新選舉
數據恢復
CAP理倫
分布式系統最多同時滿足CAP其中的兩項,不可能三項同時滿足
?
Zookeeper:滿足的是CP的兩項要求
腳本
集群統一啟動、關閉、狀態查看腳本
zk.sh
#!/bin/bash
# 運行此腳本前必須把當前機器人的公私密鑰給到目標運行機器 == 要不然每次運行此腳本時都會叫你輸入每臺目標機器的密碼
# 命令1(本機生成RSA公私密鑰):ssh-keygen -t rsa
# 命令2(將密鑰傳給目標三臺機器即192.168.19.107、192.168.19.108、192.168.19.109 ):ssh-copy-id root@目標機器IPfor currentHostName in 192.168.19.107 192.168.19.108 192.168.19.109
doecho "=================zookeeper【${currentHostName}】【$1】==============================="case $1 in"start") {ssh $currentHostName "cd /opt/module/zookeeper-3.9.1 && sh bin/zkServer.sh start"};;"stop") {ssh $currentHostName "cd /opt/module/zookeeper-3.9.1 && sh bin/zkServer.sh stop"};;"status") {ssh $currentHostName "cd /opt/module/zookeeper-3.9.1 && sh bin/zkServer.sh status"};;*) {echo "未知命令,僅支持start|stop|status"}esacdone
源碼分析(粗略)
輔助源碼
持久化
數據存儲: 集群中的數據會在內存(樹)、磁盤中各存一份
?
接口: 快照【org.apache.zookeeper.server.persistence.SnapShot】、事務記錄【org.apache.zookeeper.server.persistence.TxnLog】
?
事務日志(txnlog): ZooKeeper會將所有的寫操作以事務的形式記錄在事務日志中,這些寫操作包括創建節點、更新節點數據、刪除節點等。事務日志是一個追加寫的日志文件,用于記錄每個寫操作的詳細信息。通過事務日志,ZooKeeper可以保證數據的一致性和持久性
?
快照(snapshot): ZooKeeper定期會生成一個快照文件,用于保存當前內存中所有節點的狀態。快照文件包含了所有節點的數據和元數據信息。當ZooKeeper服務器啟動時,會首先加載最新的快照文件,然后通過回放事務日志來恢復到最新的狀態。
?
Zookeeper啟動數據恢復流程: 先加載最新的快照文件,然后通過回放事務日志來將數據恢復到最新的狀態
序列化
接口: 序列化、反序列化【org.apache.jute.Record】
服務端啟動流程
入口類: org.apache.zookeeper.server.quorum.QuorumPeerMain#main
服務端選舉Leader流程
Leader、Follower數據同步流程
概括: Follower必須去看Leader保持一致,而不是Leader跟Follower保持一致
?
【Follower】Learner: org.apache.zookeeper.server.quorum.Learner#registerWithLeader
?
【Leader】LearnerHandler: org.apache.zookeeper.server.quorum.LearnerHandler#run
服務端Leader啟動Zk過程
核心: org.apache.zookeeper.server.quorum.Leader#startZkServer
服務端Follower啟動Zk過程
核心: org.apache.zookeeper.server.quorum.Follower#followLeader
客戶端連接Zk服務端過程
核心入口: org.apache.zookeeper.ZooKeeperMain#main
?
剛興趣的同行可以進群溝通交流,內置機器人供大家愉快