ZooKeeper介紹
ZooKeeper
ZooKeeper是一個分散式的,開放原始碼的分散式應用程式協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要元件。它是一個為分散式應用提供一致性服務的軟體,提供的功能包括:配置維護、域名服務、分散式同步、組服務等。ZooKeeper的目標就是封裝好複雜易出錯的關鍵服務,將簡單易用的介面和效能高效、功能穩定的系統提供給使用者。ZooKeeper包含一個簡單的原語集, 提供Java和C的介面。ZooKeeper程式碼版本中,提供了分散式獨享鎖、選舉、佇列的介面,程式碼在zookeeper\src\recipes。其中分佈鎖和佇列有Java和C兩個版本,選舉只有Java版本。
ZooKeeper原理
ZooKeeper是以Fast Paxos演算法為基礎的,Paxos 演算法存在活鎖的問題,即當有多個proposer交錯提交時,有可能互相排斥導致沒有一個proposer能提交成功,而Fast Paxos作了一些優化,通過選舉產生一個leader (領導者),只有leader才能提交proposer,具體演算法可見Fast Paxos。因此,要想弄懂ZooKeeper首先得對Fast Paxos有所瞭解。
ZooKeeper的基本運轉流程:
1、選舉Leader。
2、同步資料。
3、選舉Leader過程中演算法有很多,但要達到的選舉標準是一致的。
4、Leader要具有最高的執行ID,類似root許可權。
5、叢集中大多數的機器得到響應並接受選出的Leader。
Paxos演算法
在paxos演算法中,分為4種角色:
Proposer :提議者
Acceptor:決策者
Client:產生議題者
Learner:最終決策學習者
上面4種角色中,提議者和決策者是很重要的,其他的2個角色在整個演算法中應該算做打醬油的,Proposer就像Client的使者,由Proposer使者拿著Client的議題去向Acceptor提議,讓Acceptor來決策。這裡上面出現了個新名詞:最終決策。現在來系統的介紹一下paxos演算法中所有的行為:
Proposer提出議題
Acceptor初步接受 或者 Acceptor初步不接受
如果上一步Acceptor初步接受則Proposer再次向Acceptor確認是否最終接受Acceptor 最終接受 或者Acceptor 最終不接受
上面Learner最終學習的目標是Acceptor們最終接受了什麼議題?注意,這裡是向所有Acceptor學習,如果有多數派個Acceptor最終接受了某提議,那就得到了最終的結果,演算法的目的就達到了。畫一幅圖來更加直觀:
Zookeeper所使用的zad協議也是類似paxos協議的。所有分散式自協商一致性演算法都是paxos演算法的簡化或者變種。Client是使用zookeeper服務的機器,Zookeeper自身包含了Acceptor, Proposer, Learner。Zookeeper領導選舉就是paxos過程,還有Client對Zookeeper寫Znode時,也是要進行Paxos過程的,因為不同Client可能連線不同的Zookeeper伺服器來寫Znode,到底哪個Client才能寫成功?需要依靠Zookeeper的paxos保證一致性,寫成功Znode的Client自然就是被最終接受了,Znode包含了寫入Client的IP與埠,其他的Client也可以讀取到這個Znode來進行Learner。也就是說在Zookeeper自身包含了Learner(因為Zookeeper為了保證自身的一致性而會進行領導選舉,所以需要有Learner的內部機制,多個Zookeeper伺服器之間需要知道現在誰是領導了),Client端也可以Learner,Learner是廣義的。
ZAB協議(ZooKeeper Atomic Broadcast原子訊息廣播協議)
zab協議所有事務請求必須由leader協調,首先leader發起proposal訊息,大多數server同意後,然後leader傳送commit訊息。
zxid編號
低32位為計數器,客戶端每次請求+1
高32位為epochID,每次選舉新leader+1
狀態和階段
Looking:系統剛啟動時或者Leader崩潰後正處於選舉狀態
Following:Follower節點所處的狀態,Follower與Leader處於資料同步階段
Leading:Leader所處狀態,當前叢集中有一個Leader為主程式
zookeeper主要分為5個階段,選舉,發現,同步,廣播
1 選舉:Looking狀態中選舉出Leader節點,Leader的lastZXID總是最新的
2 發現:Follower節點向準Leader推送FOllOWERINFO,該資訊中包含了上一週期的epoch,接受準Leader的NEWLEADER指令,檢查newEpoch有效性,準Leader要確保Follower的epoch與ZXID小於或等於自身的。
3 同步:將Follower與Leader的資料進行同步,由Leader發起同步指令,最總保持叢集資料的一致性
4 廣播:Leader廣播Proposal與Commit,Follower接受Proposal與Commit;
選舉
zab必須確保選舉出來的leader具有最大的zxid(這和raft很像啊)。這裡要注意一下,和raft一樣,選舉可能會出現兩種結果:
□上一輪的多數派(此時leader zxid可能不是最大的,需要同步的時候呼叫trunc)
□上一輪的少數派,leader zxid真的是最大的(但是這個最大的zxid沒有提交,在同步階段提交?)
過程詳解:
1、每個Follower都向其他節點傳送選自身為Leader的Vote投票請求,等待回覆;
2、Follower接受到的Vote如果比自己的ZXID更新時則投票,並更新自身的Vote,否則拒絕投票;
3、每個Follower中維護著一個投票記錄表,當某個節點收到過半的投票時,結束投票並把該Follower選為Leader,投票結束;
恢復(發現和同步)
發現
1、leader生成新的zxid和epoch,接受follower傳送來的FOllOWERINFO(含有當前節點的LastZXID)
2、leader向follower傳送NEWLEADER;Leader根據follower傳送過來的LastZXID根據資料更新策略向Follower傳送更新指令;
同步
1、SNAP:如果follower資料太老,epoch還在上上一輪,leader將傳送快照snap指令給follower同步
2、DIFF:正常同步階段
3、TRUNC:如果Follower是上一輪的少數派(通過對比ztid),傳送TRUNC指令讓follower丟棄這段資料
廣播
進入正常leader提交階段,產生遞增的zxid,接受半數投票後,再提交。
與raft的區別
我覺得zab和raft沒有本質的區別,它們唯一的不同點就是如何處理上一個leader的殘留日誌。
·raft中,需要本輪iterm有日誌提交後,才提交以前的
·zab中,在同步階段全部解決
資料整理與引用
1、https://baike.baidu.com/item/zookeeper/4836397?fr=aladdin
2、https://www.cnblogs.com/endsock/p/3480093.html
3、https://www.cnblogs.com/jxwch/p/6433310.html
4、https://www.cnblogs.com/felixzh/p/5869212.html
5、https://blog.csdn.net/liu857279611/article/details/70495413
6、https://blog.csdn.net/z69183787/article/details/54730322
相關文章
- Zookeeper 節點特性介紹
- Zookeeper介紹與叢集安裝
- Zookeeper 四字命令介紹
- ZooKeeper分散式專題(一) -- zookeeper安裝以及介紹分散式
- Zookeeper入門學習--01介紹及安裝
- Zookeeper簡介
- ZooKeeper簡介(淺入)
- 介紹如何在Spring Cloud中使用Zookeeper作為服務註冊中心SpringCloud
- Zookeeper簡介與叢集搭建
- 介紹
- ZooKeeper: 簡介, 配置及運維指南運維
- Zookeeper叢集搭建和簡介(二)
- PostSync介紹
- FontFamily介紹
- Dubbo介紹
- Yocto 介紹
- 自我介紹
- git介紹Git
- Ninja介紹
- Duktape 介紹
- 公文介紹
- jsoncpp 介紹JSON
- Ceph介紹
- MySql介紹MySql
- GraphRAG介紹
- ServletContext介紹ServletContext
- RPC介紹RPC
- JCache 介紹
- StarRocks 介紹
- maven介紹Maven
- zigbee 介紹
- Appimage介紹APP
- github介紹Github
- GO 介紹Go
- Docker介紹Docker
- Operator介紹
- shell介紹
- RabbitMQ 介紹MQ