日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Apache ZooKeeper - Leader 选举 如何保证分布式数据的一致性

發(fā)布時(shí)間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Apache ZooKeeper - Leader 选举 如何保证分布式数据的一致性 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • Pre
  • 流程圖
  • Leader 的協(xié)調(diào)過(guò)程
  • ZK 是如何實(shí)現(xiàn)的
  • 廣播模式
  • 恢復(fù)模式
  • 源碼實(shí)現(xiàn)
  • 小結(jié)


Pre

Apache ZooKeeper - 選舉Leader源碼流程深度解析

在 ZooKeeper 集群中,服務(wù)器分為 Leader 服務(wù)器、 Follower 服務(wù)器以及 Observer 服務(wù)器。

我們可以這樣認(rèn)為,Leader 選舉是一個(gè)過(guò)程,在這個(gè)過(guò)程中 ZooKeeper 主要做了兩個(gè)重要工作,一個(gè)是數(shù)據(jù)同步,另一個(gè)是選舉出新的 Leader 服務(wù)器。

今天我們繼續(xù)來(lái)看下 ZooKeeper 集群中的數(shù)據(jù)同步問題。


流程圖


Leader 的協(xié)調(diào)過(guò)程

CAP 定理是說(shuō)一個(gè)分布式系統(tǒng)不能同時(shí)滿足一致性、可用性,以及分區(qū)容錯(cuò)性。

今天要講的就是一致性。 其實(shí) ZooKeeper 中實(shí)現(xiàn)的一致性也不是強(qiáng)一致性,即集群中各個(gè)服務(wù)器上的數(shù)據(jù)每時(shí)每刻都是保持一致的特性。在 ZooKeeper 中,采用的是最終一致的特性,即經(jīng)過(guò)一段時(shí)間后,ZooKeeper 集群服務(wù)器上的數(shù)據(jù)最終保持一致的特性。

在 ZooKeeper 集群中,Leader 服務(wù)器主要負(fù)責(zé)處理事物性的請(qǐng)求,而在接收到一個(gè)客戶端的事務(wù)性請(qǐng)求操作時(shí),Leader 服務(wù)器會(huì)先向集群中的各個(gè)機(jī)器針對(duì)該條會(huì)話發(fā)起投票詢問。

要想實(shí)現(xiàn) ZooKeeper 集群中的最終一致性,我們先要確定什么情況下會(huì)對(duì) ZooKeeper 集群服務(wù)產(chǎn)生不一致的情況。

在集群初始化啟動(dòng)的時(shí)候,首先要同步集群中各個(gè)服務(wù)器上的數(shù)據(jù)。而在集群中 Leader 服務(wù)器崩潰時(shí),需要選舉出新的 Leader 而在這一過(guò)程中會(huì)導(dǎo)致各個(gè)服務(wù)器上數(shù)據(jù)的不一致,所以當(dāng)選舉出新的 Leader 服務(wù)器后需要進(jìn)行數(shù)據(jù)的同步操作。


ZK 是如何實(shí)現(xiàn)的

ZooKeeper 在集群中采用的是多數(shù)原則方式,即當(dāng)一個(gè)事務(wù)性的請(qǐng)求導(dǎo)致服務(wù)器上的數(shù)據(jù)發(fā)生改變時(shí),ZooKeeper 只要保證集群上的多數(shù)機(jī)器的數(shù)據(jù)都正確變更了,就可以保證系統(tǒng)數(shù)據(jù)的一致性。

這是因?yàn)樵谝粋€(gè) ZooKeeper 集群中,每一個(gè) Follower 服務(wù)器都可以看作是 Leader 服務(wù)器的數(shù)據(jù)副本,需要保證集群中大多數(shù)機(jī)器數(shù)據(jù)是一致的,這樣在集群中出現(xiàn)個(gè)別機(jī)器故障的時(shí)候,ZooKeeper 集群依然能夠保證穩(wěn)定運(yùn)行。

在 ZooKeeper 集群服務(wù)的運(yùn)行過(guò)程中,數(shù)據(jù)同步的過(guò)程如下圖所示。當(dāng)執(zhí)行完數(shù)據(jù)變更的會(huì)話請(qǐng)求時(shí),需要對(duì)集群中的服務(wù)器進(jìn)行數(shù)據(jù)同步。


廣播模式

ZooKeeper 在代碼層的實(shí)現(xiàn)中定義了一個(gè) HashSet 類型的變量,用來(lái)管理在集群中的 Follower 服務(wù)器,之后調(diào)用 getForwardingFollowers 函數(shù)獲取在集群中的 Follower 服務(wù)器

public class Leader(){HashSet<LearnerHandler> forwardingFollowers;public List<LearnerHandler> getForwardingFollowers() {synchronized (forwardingFollowers) {return new ArrayList<LearnerHandler>(forwardingFollowers);}}

在 ZooKeeper 集群服務(wù)器對(duì)一個(gè)事物性的請(qǐng)求操作進(jìn)行投票并通過(guò)后,Leader 服務(wù)器執(zhí)行isQuorumSynced 方法判斷該 ZooKeeper 集群中的 Follower 節(jié)點(diǎn)的連接狀態(tài),由于 isQuorumSynced 方法可以被多個(gè)線程進(jìn)行調(diào)用,所以在進(jìn)行操作的時(shí)候要通過(guò)forwardingFollowers 字段進(jìn)行加鎖操作。

之后遍歷集群中的 Follower 服務(wù)器,根據(jù)服務(wù)器 zxid、以及數(shù)據(jù)同步狀態(tài)等條件判斷服務(wù)器的執(zhí)行邏輯是否成功。之后統(tǒng)計(jì) Follower 服務(wù)器的 sid 并返回。

public boolean isQuorumSynced(QuorumVerifier qv) {synchronized (forwardingFollowers) {for (LearnerHandler learnerHandler: forwardingFollowers){if(learnerHandler.synced()){ids.add(learnerHandler.getSid());}}}}

通過(guò)上面的介紹,Leader 服務(wù)器在集群中已經(jīng)完成確定 Follower 服務(wù)器狀態(tài)等同步數(shù)據(jù)前的準(zhǔn)備工作,

接下來(lái) Leader 服務(wù)器會(huì)通過(guò) request.setTxn 方法向集群中的 Follower 服務(wù)器發(fā)送數(shù)據(jù)變更的會(huì)話請(qǐng)求。

這個(gè)過(guò)程中,我們可以把 Leader 服務(wù)器看作是 ZooKeeper 服務(wù)中的客戶端,而其向集群中 Follower 服務(wù)器發(fā)送數(shù)據(jù)更新請(qǐng)求,集群中的 Follower 服務(wù)器收到請(qǐng)求后會(huì)處理該會(huì)話,之后進(jìn)行數(shù)據(jù)變更操作。

如下面的代碼所示,在底層實(shí)現(xiàn)中,通過(guò)調(diào)用 request 請(qǐng)求對(duì)象的 setTxn 方法向 Follower 服務(wù)器發(fā)送請(qǐng)求,在 setTxn 函數(shù)中我們傳入的參數(shù)有操作類型字段 CONFIG_NODE,表明該操作是數(shù)據(jù)同步操作。

request.setTxn(new SetDataTxn(ZooDefs.CONFIG_NODE, request.qv.toString().getBytes(), -1));

恢復(fù)模式

介紹完 Leader 節(jié)點(diǎn)如何管理 Follower 服務(wù)器進(jìn)行數(shù)據(jù)同步后,接下來(lái)我們看一下當(dāng) Leader 服務(wù)器崩潰后 ZooKeeper 集群又是如何進(jìn)行數(shù)據(jù)的恢復(fù)和同步的。

當(dāng) ZooKeeper 集群中一個(gè) Leader 服務(wù)器失效時(shí),會(huì)重新在 Follower 服務(wù)器中選舉出一個(gè)新的服務(wù)器作為 Leader 服務(wù)器。

而 ZooKeeper 服務(wù)往往處在高并發(fā)的使用場(chǎng)景中,如果在這個(gè)過(guò)程中有新的事務(wù)性請(qǐng)求操作,應(yīng)該如何處理呢? 由于此時(shí)集群中不存在 Leader 服務(wù)器了,理論上 ZooKeeper 會(huì)直接丟失該條請(qǐng)求,會(huì)話不進(jìn)行處理,但是這樣做在實(shí)際的生產(chǎn)中顯然是不行的,那么 ZooKeeper 具體是怎么做的呢?

在 ZooKeeper 中,重新選舉 Leader 服務(wù)器會(huì)經(jīng)歷一段時(shí)間,因此理論上在 ZooKeeper 集群中會(huì)短暫的沒有 Leader 服務(wù)器,在這種情況下接收到事務(wù)性請(qǐng)求操作的時(shí)候,ZooKeeper 服務(wù)會(huì)先將這個(gè)會(huì)話進(jìn)行掛起操作,掛起的會(huì)話不會(huì)計(jì)算會(huì)話的超時(shí)時(shí)間,之后在 Leader 服務(wù)器產(chǎn)生后系統(tǒng)會(huì)同步執(zhí)行這些會(huì)話操作。


源碼實(shí)現(xiàn)

提到過(guò)一個(gè) LearnerHandler 類, 當(dāng)時(shí)我們只是簡(jiǎn)單地從服務(wù)器之間的通信和協(xié)同工作的角度去分析了該類的作用。而 LearnerHandler 類其實(shí)可以看作是所有 Learner 服務(wù)器內(nèi)部工作的處理者,它所負(fù)責(zé)的工作有:進(jìn)行 Follower、Observer 服務(wù)器與 Leader 服務(wù)器的數(shù)據(jù)同步、事務(wù)性會(huì)話請(qǐng)求的轉(zhuǎn)發(fā)以及 Proposal 提議投票等功能。

LearnerHandler 是一個(gè)多線程的類,在 ZooKeeper 集群服務(wù)運(yùn)行過(guò)程中,一個(gè) Follower 或 Observer 服務(wù)器就對(duì)應(yīng)一個(gè) LearnerHandler 。在集群服務(wù)器彼此協(xié)調(diào)工作的過(guò)程中,Leader 服務(wù)器會(huì)與每一個(gè) Learner 服務(wù)器維持一個(gè)長(zhǎng)連接,并啟動(dòng)一個(gè)單獨(dú)的 LearnerHandler 線程進(jìn)行處理。

如下面的代碼所示,在 LearnerHandler 線程類中,最核心的方法就是 run 方法,處理數(shù)據(jù)同步等功能都在該方法中進(jìn)行調(diào)用。首先通過(guò) syncFollower 函數(shù)判斷數(shù)據(jù)同步的方式是否是快照方式。如果是快照方式,就將 Leader 服務(wù)器上的數(shù)據(jù)操作日志 dump 出來(lái)發(fā)送給 Follower 等服務(wù)器,在 Follower 等服務(wù)器接收到數(shù)據(jù)操作日志后,在本地執(zhí)行該日志,最終完成數(shù)據(jù)的同步操作。

public void run() {boolean needSnap = syncFollower(peerLastZxid, leader.zk.getZKDatabase(), leader);if(needSnap){leader.zk.getZKDatabase().serializeSnapshot(oa);oa.writeString("BenWasHere", "signature");bufferedOutput.flush();}}

小結(jié)

到這里我們就對(duì) ZooKeeper 中數(shù)據(jù)一致性的解決原理和底層實(shí)現(xiàn)都做了較為詳細(xì)的介紹。我們總結(jié)一下,ZooKeeper 集群在處理一致性問題的時(shí)候基本采用了兩種方式來(lái)協(xié)調(diào)集群中的服務(wù)器工作,分別是恢復(fù)模式和廣播模式。

  • 恢復(fù)模式:當(dāng) ZooKeeper 集群中的 Leader 服務(wù)器崩潰后,ZooKeeper 集群就采用恢復(fù)模式的方式進(jìn)行工作,在這個(gè)工程中,ZooKeeper 集群會(huì)首先進(jìn)行 Leader 節(jié)點(diǎn)服務(wù)器的重新選擇,之后在選舉出 Leader 服務(wù)器后對(duì)系統(tǒng)中所有的服務(wù)器進(jìn)行數(shù)據(jù)同步進(jìn)而保證集群中服務(wù)器上的數(shù)據(jù)的一致性。

  • 廣播模式:當(dāng) ZooKeeper 集群中具有 Leader 服務(wù)器,并且可以正常工作時(shí),集群中又有新的 Follower 服務(wù)器加入 ZooKeeper 中參與工作,這種情況常常發(fā)生在系統(tǒng)性能到達(dá)瓶頸,進(jìn)而對(duì)系統(tǒng)進(jìn)行動(dòng)態(tài)擴(kuò)容的使用場(chǎng)景。在這種情況下,如果不做任何操作,那么新加入的服務(wù)器作為 Follower 服務(wù)器,其上的數(shù)據(jù)與 ZooKeeper 集群中其他服務(wù)器上的數(shù)據(jù)不一致。當(dāng)有新的查詢會(huì)話請(qǐng)求發(fā)送到 ZooKeeper 集群進(jìn)行處理,而恰巧該請(qǐng)求實(shí)際被分發(fā)給這臺(tái)新加入的 Follower 機(jī)器進(jìn)行處理,就會(huì)導(dǎo)致明明在集群中存在的數(shù)據(jù),在這臺(tái)服務(wù)器上卻查詢不到,導(dǎo)致數(shù)據(jù)查詢不一致的情況。因此,在當(dāng)有新的 Follower 服務(wù)器加入 ZooKeeper 集群中的時(shí)候,該臺(tái)服務(wù)器會(huì)在恢復(fù)模式下啟動(dòng),并找到集群中的 Leader 節(jié)點(diǎn)服務(wù)器,并同該 Leader 服務(wù)器進(jìn)行數(shù)據(jù)同步。

走了~

總結(jié)

以上是生活随笔為你收集整理的Apache ZooKeeper - Leader 选举 如何保证分布式数据的一致性的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。