ZooKeeper面試專題(2020.5月整理)

歡迎關注
CSDN:程序員小羊
微信公衆號:程序員小羊

1、什麼是Zookeeper?

ZooKeeper 是一個開放源碼的分佈式協調服務,它是集羣的管理者,監視着集羣中各個節點的狀態根據節點提交的反饋進行下一步合理操作。最終,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。分佈式應用程序可以基於 Zookeeper 實現諸如數據發佈/訂閱、負載均衡、命名服務、分佈式協調/通知、集羣管理、Master 選舉、分佈式鎖和分佈式隊列等功能。

2、Zookeeper 如何保證了分佈式一致性特性?

  1. 順序一致性
  2. 原子性
  3. 單一視圖
  4. 可靠性
  5. 實時性(最終一致性)

客戶端的讀請求可以被集羣中的任意一臺機器處理,如果讀請求在節點上註冊了監聽器,這個監聽器也是由所連接的 zookeeper 機器來處理。對於寫請求,這些請求會同時發給其他 zookeeper 機器並且達成一致後,請求才會返回成功。因此,隨着 zookeeper 的集羣機器增多,讀請求的吞吐會提高但是寫請求的吞吐會下降。有序性是 zookeeper 中非常重要的一個特性,所有的更新都是全局有序的,每個更新都有一個唯一的時間戳,這個時間戳稱爲 zxid(Zookeeper Transaction Id)。而讀請求只會相對於更新有序,也就是讀請求的返回結果中會帶有這個zookeeper 最新的 zxid

3、ZooKeeper 提供了什麼?

  1. 文件系統
  2. 通知機制

4、Zookeeper 文件系統

Zookeeper 提供一個多層級的節點命名空間(節點稱爲 znode)。與文件系統不同的是,這些節點都可以設置關聯的數據,而文件系統中只有文件節點可以存放數據而目錄節點不行。
Zookeeper 爲了保證高吞吐和低延遲,在內存中維護了這個樹狀的目錄結構,這種特性使得 Zookeeper 不能用於存放大量的數據,每個節點的存放數據上限爲1M。

5、ZAB 協議?

ZAB 協議是爲分佈式協調服務 Zookeeper 專門設計的一種支持崩潰恢復的原子廣播協議。
ZAB 協議包括兩種基本的模式:崩潰恢復和消息廣播 。
當整個 zookeeper 集羣剛剛啓動或者 Leader 服務器宕機、重啓或者網絡故障導致不存在過半的服務器與 Leader 服務器保持正常通信時,所有進程(服務器)進入崩潰恢復模式,首先選舉產生新的 Leader 服務器,然後集羣中 Follower 服務器開始與新的 Leader 服務器進行數據同步,當集羣中超過半數機器與該 Leader服務器完成數據同步之後,退出恢復模式進入消息廣播模式,Leader 服務器開始接收客戶端的事務請求生成事物提案來進行事務請求處理

6、四種類型的數據節點 Znode

  1. PERSISTENT-持久節點
    除非手動刪除,否則節點一直存在於 Zookeeper 上
  2. EPHEMERAL-臨時節點
    臨時節點的生命週期與客戶端會話綁定,一旦客戶端會話失效(客戶端與zookeeper 連接斷開不一定會話失效),那麼這個客戶端創建的所有臨時節點都會被移除。
  3. PERSISTENT_SEQUENTIAL-持久順序節點
    基本特性同持久節點,只是增加了順序屬性,節點名後邊會追加一個由父節點維護的自增整型數字。
  4. EPHEMERAL_SEQUENTIAL-臨時順序節點
    基本特性同臨時節點,增加了順序屬性,節點名後邊會追加一個由父節點維護的自增整型數字。

7、Zookeeper Watcher 機制 – 數據變更通知

Zookeeper 允許客戶端向服務端的某個 Znode 註冊一個 Watcher 監聽,當服務端的一些指定事件觸發了這個 Watcher,服務端會向指定客戶端發送一個事件通知來實現分佈式的通知功能,然後客戶端根據 Watcher 通知狀態和事件類型做出業務上的改變。
工作機制:

  1. 客戶端註冊 watcher 2、服務端處理 watcher
  2. 客戶端回調 watcher

Watcher 特性總結
3. 一次性
無論是服務端還是客戶端,一旦一個 Watcher 被觸發,Zookeeper 都會將其從相應的存儲中移除。這樣的設計有效的減輕了服務端的壓力,不然對於更新非常頻繁的節點,服務端會不斷的向客戶端發送事件通知,無論對於網絡還是服務端的壓力都非常大。
4. 客戶端串行執行
客戶端 Watcher 回調的過程是一個串行同步的過程。
5. 輕量

  • Watcher 通知非常簡單,只會告訴客戶端發生了事件,而不會說明事件的具體內容。
  • 客戶端向服務端註冊 Watcher 的時候,並不會把客戶端真實的 Watcher 對象實體傳遞到服務端,僅僅是在客戶端請求中使用 boolean 類型屬性進行了標記。
  1. watcher event 異步發送 watcher 的通知事件從 server 發送到 client 是異步的,這就存在一個問題,不同的客戶端和服務器之間通過 socket 進行通信,由於網絡延遲或其他因素導致客戶端在不通的時刻監聽到事件,由於 Zookeeper 本身提供了 ordering guarantee,即客戶端監聽事件後,纔會感知它所監視 znode發生了變化。所以我們使用
    Zookeeper 不能期望能夠監控到節點每次的變化。Zookeeper 只能保證最終的一致性,而無法保證強一致性。
  2. 註冊 watcher getData、exists、getChildren
  3. 觸發 watcher create、delete、setData
  4. 當一個客戶端連接到一個新的服務器上時,watch 將會被以任意會話事件觸發。當與一個服務器失去連接的時候,是無法接收到 watch 的。而當 client 重新連接時,如果需要的話,所有先前註冊過的 watch,都會被重新註冊。通常這是完全透明的。只有在一個特殊情況下,watch 可能會丟失:對於一個未創建的 znode的 exist watch,如果在客戶端斷開連接期間被創建了,並且隨後在客戶端連接上之前又刪除了,這種情況下,這個 watch 事件可能會被丟失。

8、客戶端註冊 Watcher 實現

  1. 調用 getData()/getChildren()/exist()三個 API,傳入 Watcher 對象
  2. 標記請求 request,封裝 Watcher 到 WatchRegistration
  3. 封裝成 Packet 對象,發服務端發送 request
  4. 收到服務端響應後,將 Watcher 註冊到 ZKWatcherManager 中進行管理
  5. 請求返回,完成註冊。

9、 服務端處理 Watcher 實現

1. 服務端接收 Watcher 並存儲
接收到客戶端請求,處理請求判斷是否需要註冊 Watcher,需要的話將數據節點的節點路徑和 ServerCnxn(ServerCnxn 代表一個客戶端和服務端的連接,實現了 Watcher 的
process 接口,此時可以看成一個 Watcher 對象)存儲在WatcherManager 的 WatchTable 和 watch2Paths 中去。
2. Watcher 觸發
以服務端接收到 setData() 事務請求觸發 NodeDataChanged 事件爲例:

  1. 封裝 WatchedEvent將通知狀態(SyncConnected)、事件類型(NodeDataChanged)以及節點路徑封裝成一個 WatchedEvent 對象
  2. 查詢 Watcher從 WatchTable 中根據節點路徑查找 Watcher
  3. 沒找到;說明沒有客戶端在該數據節點上註冊過 Watcher
  4. 找到;提取並從 WatchTable 和 Watch2Paths 中刪除對應 Watcher(從這裏可以看出 Watcher 在服務端是一次性的,觸發一次就失效了)

3、調用 process 方法來觸發 Watcher
這裏 process 主要就是通過 ServerCnxn 對應的 TCP 連接發送 Watcher 事件通知

10、客戶端回調 Watcher

客戶端 SendThread 線程接收事件通知,交由 EventThread 線程回調 Watcher。客戶端的 Watcher 機制同樣是一次性的,一旦被觸發後,該 Watcher 就失效了。

11、ACL 權限控制機制

UGO(User/Group/Others)
目前在 Linux/Unix 文件系統中使用,也是使用最廣泛的權限控制方式。是一種粗粒度的文件系統權限控制模式。
ACL(Access Control List)訪問控制列表包括三個方面:
權限模式(Scheme)

  1. IP:從 IP 地址粒度進行權限控制
  2. Digest:最常用,用類似於 username:password 的權限標識來進行權限配置,便於區分不同應用來進行權限控制
  3. World:最開放的權限控制方式,是一種特殊的 digest 模式,只有一個權限標識“world:anyone”
  4. Super:超級用戶
    授權對象
    授權對象指的是權限賦予的用戶或一個指定實體,例如 IP 地址或是機器燈。
    權限 Permission
  5. CREATE:數據節點創建權限,允許授權對象在該 Znode 下創建子節點
  6. DELETE:子節點刪除權限,允許授權對象刪除該數據節點的子節點
  7. READ:數據節點的讀取權限,允許授權對象訪問該數據節點並讀取其數據內容或子節點列表等
  8. WRITE:數據節點更新權限,允許授權對象對該數據節點進行更新操作
  9. ADMIN:數據節點管理權限,允許授權對象對該數據節點進行 ACL 相關設置操作

12、Chroot 特性

3.2.0 版本後,添加了 Chroot 特性,該特性允許每個客戶端爲自己設置一個命名空間。如果一個客戶端設置了 Chroot,那麼該客戶端對服務器的任何操作,都將會被限制在其自己的命名空間下。
通過設置 Chroot,能夠將一個客戶端應用於 Zookeeper 服務端的一顆子樹相對應,在那些多個應用公用一個 Zookeeper 進羣的場景下,對實現不同應用間的相互隔離非常有幫助。

13、會話管理

分桶策略:將類似的會話放在同一區塊中進行管理,以便於 Zookeeper 對會話進行不同區塊的隔離處理以及同一區塊的統一處理。
分配原則:每個會話的“下次超時時間點”(ExpirationTime) 計算公式:

ExpirationTime_ = currentTime + sessionTimeout
ExpirationTime = (ExpirationTime_ / ExpirationInrerval + 1) * ExpirationInterval , ExpirationInterval 是指 Zookeeper 會話超時檢查時間間隔,默認 tickTime

14、服務器角色

Leader

  1. 事務請求的唯一調度和處理者,保證集羣事務處理的順序性
  2. 集羣內部各服務的調度者

Follower

  1. 處理客戶端的非事務請求,轉發事務請求給 Leader 服務器
  2. 參與事務請求 Proposal 的投票
  3. 參與 Leader 選舉投票

Observer

  1. 3.0版本以後引入的一個服務器角色,在不影響集羣事務處理能力的基礎上提升集羣的非事務處理能力
  2. 處理客戶端的非事務請求,轉發事務請求給 Leader 服務器
  3. 不參與任何形式的投票

15、Zookeeper 下 Server 工作狀態

服務器具有四種狀態,分別是 LOOKING、FOLLOWING、LEADING、OBSERVING。

  1. LOOKING:尋找 Leader 狀態。當服務器處於該狀態時,它會認爲當前集羣中沒有 Leader,因此需要進入 Leader 選舉狀態。
  2. FOLLOWING:跟隨者狀態。表明當前服務器角色是 Follower。
  3. LEADING:領導者狀態。表明當前服務器角色是 Leader。
  4. OBSERVING:觀察者狀態。表明當前服務器角色是 Observer。

16、數據同步

整個集羣完成 Leader 選舉之後,Learner(Follower 和 Observer 的統稱)迴向Leader 服務器進行註冊。當 Learner 服務器想 Leader 服務器完成註冊後,進入數據同步環節。
數據同步流程:(均以消息傳遞的方式進行)
Learner 向 Learder 注 冊數據同步
同步確認

Zookeeper 的數據同步通常分爲四類:

  1. 直接差異化同步(DIFF 同步)
  2. 先回滾再差異化同步(TRUNC+DIFF 同步)
  3. 僅回滾同步(TRUNC 同步)
  4. 全量同步(SNAP 同步)
    在進行數據同步前,Leader 服務器會完成數據同步初始化:
    peerLastZxid:
  • 從 learner 服務器註冊時發送的 ACKEPOCH 消息中提取 lastZxid(該Learner 服務器最後處理的 ZXID)
    minCommittedLog:
  • Leader 服務器 Proposal 緩存隊列 committedLog 中最小 ZXID
    maxCommittedLog:
  • Leader 服務器 Proposal 緩存隊列 committedLog 中最大 ZXID
    直接差異化同步(DIFF 同步)
  • 場景:peerLastZxid 介於 minCommittedLog 和 maxCommittedLog之間
    先回滾再差異化同步(TRUNC+DIFF 同步)
  • 場景:當新的 Leader 服務器發現某個 Learner 服務器包含了一條自己沒有的事務記錄,那麼就需要讓該 Learner 服務器進行事務回滾–回滾到 Leader服務器上存在的,同時也是最接近於 peerLastZxid 的 ZXID
    僅回滾同步(TRUNC 同步)
  • 場景:peerLastZxid 大於 maxCommittedLog全量同步(SNAP 同步)
  • 場景一:peerLastZxid 小於 minCommittedLog
  • 場景二:Leader 服務器上沒有 Proposal 緩存隊列且 peerLastZxid 不等於 lastProcessZxid

17、zookeeper 是如何保證事務的順序一致性的?

zookeeper 採用了全局遞增的事務 Id 來標識,所有的 proposal(提議)都在被提出的時候加上了 zxid,zxid 實際上是一個 64 位的數字,高 32 位是 epoch(時期; 紀元; 世; 新時代)用來標識 leader 週期,如果有新的 leader 產生出來,epoch會自增,低 32 位用來遞增計數。當新產生 proposal 的時候,會依據數據庫的兩階段過程,首先會向其他的
server 發出事務執行請求,如果超過半數的機器都能執行並且能夠成功,那麼就會開始執行。

18、zk 節點宕機如何處理?

Zookeeper 本身也是集羣,推薦配置不少於 3 個服務器。Zookeeper 自身也要保證當一個節點宕機時,其他節點會繼續提供服務。如果是一個 Follower 宕機,還有 2 臺服務器提供訪問,因爲 Zookeeper 上的數據是有多個副本的,數據並不會丟失;
如果是一個 Leader 宕機,Zookeeper 會選舉出新的 Leader。
ZK 集羣的機制是隻要超過半數的節點正常,集羣就能正常提供服務。只有在 ZK節點掛得太多,只剩一半或不到一半節點能工作,集羣才失效。所以
3個節點的 cluster 可以掛掉 1 個節點(leader 可以得到 2 票>1.5)
2 個節點的 cluster 就不能掛掉任何 1 個節點了(leader 可以得到 1 票<=1)

19、zookeeper 負載均衡和 nginx 負載均衡區別

zk 的負載均衡是可以調控,nginx 只是能調權重,其他需要可控的都需要自己寫插件;但是 nginx 的吞吐量比 zk 大很多,應該說按業務選擇用哪種方式。

20、分佈式集羣中爲什麼會有 Master?

在分佈式環境中,有些業務邏輯只需要集羣中的某一臺機器進行執行,其他的機器可以共享這個結果,這樣可以大大減少重複計算,提高性能,於是就需要進行leader 選舉。

21、Zookeeper 有哪幾種幾種部署模式?

部署模式:單機模式、僞集羣模式、集羣模式

22、集羣最少要幾臺機器,集羣規則是怎樣的?

集羣規則爲 2N+1 臺,N>0,即 3 臺

23、集羣支持動態添加機器嗎?

其實就是水平擴容了,Zookeeper 在這方面不太好。兩種方式:
全部重啓:關閉所有 Zookeeper 服務,修改配置之後啓動。不影響之前客戶端的會話。
逐個重啓:在過半存活即可用的原則下,一臺機器重啓不影響整個集羣對外提供服務。這是比較常用的方式。
3.5版本開始支持動態擴容

24、Zookeeper 對節點的 watch監聽通知是永久的嗎?爲什麼不是永久的?

不是。官方聲明:一個 Watch 事件是一個一次性的觸發器,當被設置了 Watch的數據發生了改變的時候,則服務器將這個改變發送給設置了 Watch 的客戶端,以便通知它們。爲什麼不是永久的,舉個例子,如果服務端變動頻繁,而監聽的客戶端很多情況下,每次變動都要通知到所有的客戶端,給網絡和服務器造成很大壓力。一般是客戶端執行
getData(“/節點 A”,true),如果節點 A 發生了變更或刪除,客戶端會得到它的 watch 事件,但是在之後節點 A 又發生了變更,而客戶端又沒有設置 watch 事件,就不再給客戶端
發送。
在實際應用中,很多情況下,我們的客戶端不需要知道服務端的每一次變動,我只要最新的數據即可。

25、Zookeeper 的 java 客戶端都有哪些?

java 客戶端:zk 自帶的 zkclient 及 Apache 開源的 Curator。

26、chubby 是什麼,和 zookeeper 比你怎麼看 ?

chubby 是 google 的, 完全 實現 paxos 算法 ,不 開源 。zookeeper 是 chubby的開 源實 現, 使用 zab 協議 ,paxos 算法 的變 種。

27、說幾個 zookeeper 常用的命令。

常用 命令 :ls get set create delete 等。

28、ZAB 和 Paxos 算法的聯繫與區別?

相同點:

  1. 兩者 都存 在一 個類 似於 Leader 進程 的角 色 ,由其 負責 協調 多個 Follower 進程的運 行
  2. Leader 進程 都會 等待 超過 半數 的 Follower 做出 正確 的反 饋後 ,纔會 將一 個提案進 行提 交
  3. ZAB 協議 中, 每個 Proposal 中都 包含 一個 epoch 值來 代表 當前 的 Leader週期 ,Paxos 中名 字爲 Ballot
    不同點:

ZAB 用來 構建 高可 用的 分佈 式數 據主 備系 統( Zookeeper), Paxos 是用 來構 建分佈 式一 致性 狀態 機系 統。

29、Zookeeper 的典型應用場景

Zookeeper 是一個典型的發佈/訂閱模式的分佈式數據管理與協調框架,開發人員可以使用它來進行分佈式數據的發佈和訂閱。
通過對 Zookeeper 中豐富的數據節點進行交叉使用,配合 Watcher 事件通知機制,可以非常方便的構建一系列分佈式應用中年都會涉及的核心功能,如:

  1. 數據發佈/訂閱
  2. 負載均衡
  3. 命名服務
  4. 分佈式協調/通知
  5. 集羣管理
  6. Master 選舉
  7. 分佈式鎖
  8. 分佈式隊列

30、數據發佈/訂閱

數據發佈/訂閱系統,即所謂的配置中心,顧名思義就是發佈者發佈數據供訂閱者進行數據訂閱。
目的
動態獲取數據(配置信息)
實現數據(配置信息)的集中式管理和數據的動態更新
設計模式
Push 模式
Pull 模式
數據(配置信息)特性

  1. 數據量通常比較小
  2. 數據內容在運行時會發生動態更新
  3. 集羣中各機器共享,配置一致
    如:機器列表信息、運行時開關配置、數據庫配置信息等
    基於 Zookeeper 的實現方式
  • 數據存儲:將數據(配置信息)存儲到 Zookeeper 上的一個數據節點
  • 數據獲取:應用在啓動初始化節點從 Zookeeper 數據節點讀取數據,並在該節點上註冊一個數據變更 Watcher
  • 數據變更:當變更數據時,更新 Zookeeper 對應節點數據,Zookeeper會將數據變更通知發到各客戶端,客戶端接到通知後重新讀取變更後的數據即可。

31、zk 的命名服務

命名服務是指通過指定的名字來獲取資源或者服務的地址,利用 zk 創建一個全局的路徑,這個路徑就可以作爲一個名字,指向集羣中的集羣,提供的服務的地址,或者一個遠程的對象等等。

32、分佈式通知和協調

對於系統調度來說:操作人員發送通知實際是通過控制檯改變某個節點的狀態,然後 zk 將這些變化發送給註冊了這個節點的 watcher 的所有客戶端。 對於執行情況彙報:每個工作進程都在某個目錄下創建一個臨時節點。並攜帶工作的進度數據,這樣彙總的進程可以監控目錄子節點的變化獲得工作進度的實時的全局情況。

33、zk 的命名服務(文件系統)

命名服務是指通過指定的名字來獲取資源或者服務的地址,利用 zk 創建一個全局的路徑,即是唯一的路徑,這個路徑就可以作爲一個名字,指向集羣中的集羣,提供的服務的地址,或者一個遠程的對象等等。

34、zk 的配置管理(文件系統、通知機制)

程序分佈式的部署在不同的機器上,將程序的配置信息放在 zk 的 znode 下,當有配置發生改變時,也就是 znode 發生變化時,可以通過改變 zk 中某個目錄節點的內容,利用
watcher 通知給各個客戶端,從而更改配置。

35、Zookeeper 集羣管理(文件系統、通知機制)**

所謂集羣管理無在乎兩點:是否有機器退出和加入、選舉 master。對於第一點,所有機器約定在父目錄下創建臨時目錄節點,然後監聽父目錄節點的子節點變化消息。一旦有機器掛掉,該機器與 zookeeper 的連接斷開,其所創建的臨時目錄節點被刪除,所有其他機器都收到通知:某個兄弟目錄被刪除,於是,所有人都知道:它上船了。
新機器加入也是類似,所有機器收到通知:新兄弟目錄加入,highcount 又有了,對於第二點,我們稍微改變一下,所有機器創建臨時順序編號目錄節點,每次選取編號最小的機器作爲 master 就好。

36、Zookeeper 分佈式鎖(文件系統、通知機制**)

有了 zookeeper 的一致性文件系統,鎖的問題變得容易。鎖服務可以分爲兩類,一個是保持獨佔,另一個是控制時序 對於第一類,我們將 zookeeper 上的一個 znode 看作是一把鎖,通過 createznode的方式來實現。所有客戶端都去創建 /distribute_lock 節點,最終成功創建的那個客戶端也即擁有了這把鎖。用完刪除掉自己創建的 distribute_lock 節點就釋放出鎖。
對於第二類, /distribute_lock 已經預先存在,所有客戶端在它下面創建臨時順序編號目錄節點,和選 master 一樣,編號最小的獲得鎖,用完刪除,依次方便。

37、Zookeeper 隊列管理(文件系統、通知機制)

兩種類型的隊列:

  1. 同步隊列,當一個隊列的成員都聚齊時,這個隊列纔可用,否則一直等待所有成員到達。
  2. 隊列按照 FIFO 方式進行入隊和出隊操作。

第一類,在約定目錄下創建臨時目錄節點,監聽節點數目是否是我們要求的數目。
第二類,和分佈式鎖服務中的控制時序場景基本原理一致,入列有編號,出列按編號。在特定的目錄下創建 PERSISTENT_SEQUENTIAL 節點,創建成功時Watcher 通知等待的隊列,隊列刪除序列號最小的節點用以消費。此場景下Zookeeper 的 znode 用於消息存儲,znode 存儲的數據就是消息隊列中的消息內容,SEQUENTIAL 序列號就是消息的編
號,按序取出即可。由於創建的節點是持久化的,所以不必擔心隊列消息的丟失問題。

38、Zookeeper 角色

Zookeeper 集羣是一個基於主從複製的高可用集羣,每個服務器承擔如下三種角色中的一種
Leader

  1. 一個 Zookeeper 集羣同一時間只會有一個實際工作的 Leader,它會發起並維護與各 Follwer及 Observer 間的心跳。
  2. 所有的寫操作必須要通過 Leader 完成再由 Leader 將寫操作廣播給其它服務器。 只要有超過半數節點(不包括 observeer 節點) 寫入成功,該寫請求就會被提交(類2PC 協議)。

Follower

  1. 一個 Zookeeper 集羣可能同時存在多個 Follower,它會響應 Leader 的心跳,
  2. Follower 可直接處理並返回客戶端的讀請求,同時會將寫請求轉發給 Leader 處理,
  3. 並且負責在 Leader 處理寫請求時對請求進行投票。
    Observer
    角色與 Follower 類似,但是無投票權。 Zookeeper 需保證高可用和強一致性,爲了支持更多的客戶端,需要增加更多 Server; Server 增多,投票階段延遲增大,影響性能; 引入 Observer,Observer 不參與投票; bservers 接受客戶端的連接,並將寫請求轉發給 leader 節點; 加入更多 Observer 節點,提高伸縮性,同時不影響吞吐率。
    在這裏插入圖片描述

39、事務編號 Zxid(事務請求計數器+ epoch)

在 ZAB ( ZooKeeper Atomic Broadcast , ZooKeeper 原子消息廣播協議) 協議的事務編號 Zxid設計中, Zxid 是一個 64 位的數字,其中低 32 位是一個簡單的單調遞增的計數器, 針對客戶端每一個事務請求,計數器加 1;而高 32 位則代表 Leader 週期 epoch 的編號, 每個當選產生一個新的 Leader 服務器,就會從這個 Leader 服務器上取出其本地日誌中最大事務的 ZXID,並從中讀取epoch 值,然後加 1,以此作爲新的 epoch,並將低 32 位從 0 開始計數。Zxid(Transaction id) 類似於 RDBMS 中的事務 ID,用於標識一次更新操作的 Proposal(提議)
ID。爲了保證順序性,該 zkid 必須單調遞增。

40、epoch

epoch:可以理解爲當前集羣所處的年代或者週期,每個 leader 就像皇帝,都有自己的年號,所以每次改朝換代, leader 變更之後,都會在前一個年代的基礎上加 1。這樣就算舊的 leader 崩潰恢復之後,也沒有人聽他的了,因爲 follower 只聽從當前年代的 leader 的命令。

41、Zab 協議有兩種模式-恢復模式(選主)、廣播模式(同步)

Zab 協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步) 。當服務啓動或者在領導者崩潰後, Zab 就進入了恢復模式,當領導者被選舉出來,且大多數 Server完成了和 leader 的狀態同步以後,恢復模式就結束了。狀態同步保證了 leader 和 Server 具有相同的系統狀態。

42、Leader election(選舉階段-選出準 Leader)

Leader election(選舉階段) : 節點在一開始都處於選舉階段,只要有一個節點得到超半數節點的票數,它就可以當選準 leader。只有到達 廣播階段(broadcast) 準 leader纔會成爲真正的 leader。這一階段的目的是就是爲了選出一個準 leader,然後進入下一個階段

43、Discovery(發現階段-接受提議、生成 epoch、接受 epoch)

Discovery(發現階段) : 在這個階段, followers 跟準 leader 進行通信,同步 followers最近接收的事務提議。這個一階段的主要目的是發現當前大多數節點接收的最新提議,並且準 leader 生成新的 epoch,讓 followers 接受,更新它們的 accepted Epoch一個 follower 只會連接一個 leader, 如果有一個節點 f 認爲另一個 follower p 是 leader, f在嘗試連接 p 時會被拒絕, f 被拒絕之後,就會進入重新選舉階段

44、Synchronization(同步階段-同步 follower 副本)

Synchronization(同步階段) : 同步階段主要是利用 leader 前一階段獲得的最新提議歷史,同步集羣中所有的副本。 只有當 大多數節點都同步完成,準 leader 纔會成爲真正的 leader。follower 只會接收 zxid 比自己的 lastZxid 大的提議。

45、Broadcast(廣播階段-leader 消息廣播)

Broadcast(廣播階段) : 到了這個階段, Zookeeper 集羣才能正式對外提供事務服務,並且 leader 可以進行消息廣播。同時如果有新的節點加入,還需要對新節點進行同步

46、ZAB 協議 JAVA 實現(FLE-發現階段和同步合併爲 Recovery Phase(恢復階段) )

協議的 Java 版本實現跟上面的定義有些不同,選舉階段使用的是 Fast Leader Election(FLE),它包含了 選舉的發現職責。因爲 FLE 會選舉擁有最新提議歷史的節點作爲leader,這樣就省去了發現最新提議的步驟。實際的實現將 發現階段 和 同步合併爲 Recovery Phase(恢復階段)。所以, ZAB 的實現只有三個階段: Fast Leader Election; Recovery Phase; Broadcast Phase。

47、投票機制

每個 sever 首先給自己投票, 然後用自己的選票和其他 sever 選票對比, 權重大的勝出,使用權重較大的更新自身選票箱。 具體選舉過程如下:

  1. 每個 Server 啓動以後都詢問其它的 Server 它要投票給誰。對於其他 server 的詢問,server 每次根據自己的狀態都回復自己推薦的 leader 的 id 和上一次處理事務的
    zxid(系統啓動時每個 server 都會推薦自己)
  2. 收到所有 Server 回覆以後,就計算出 zxid 最大的哪個 Server,並將這個 Server 相關信息設置成下一次要投票的 Server。
  3. 計算這過程中獲得票數最多的的 sever 爲獲勝者,如果獲勝者的票數超過半數,則改server 被選爲 leader。否則,繼續這個過程,直到 leader 被選舉出來
  4. leader 就會開始等待 server 連接
  5. Follower 連接 leader,將最大的 zxid 發送給 leader
  6. Leader 根據 follower 的 zxid 確定同步點,至此選舉階段完成。
  7. 選舉階段完成 Leader 同步後通知 follower 已經成爲 uptodate 狀態
  8. Follower 收到 uptodate 消息後,又可以重新接受 client 的請求進行服務了

目前有 5 臺服務器,每臺服務器均沒有數據,它們的編號分別是 1,2,3,4,5,按編號依次啓動,它們的選擇舉過程如下:

  1. 服務器 1 啓動,給自己投票,然後發投票信息,由於其它機器還沒有啓動所以它收不到反饋信息,服務器 1 的狀態一直屬於 Looking。
  2. 服務器 2 啓動,給自己投票,同時與之前啓動的服務器 1 交換結果,由於服務器 2 的編號大所以服務器 2 勝出,但此時投票數沒有大於半數,所以兩個服務器的狀態依然是
    LOOKING。
  3. 服務器 3 啓動,給自己投票,同時與之前啓動的服務器 1,2 交換信息,由於服務器 3 的編號最大所以服務器 3 勝出,此時投票數正好大於半數,所以服務器 3 成爲領導者, 服務器1,2 成爲小弟。
  4. 服務器 4 啓動,給自己投票,同時與之前啓動的服務器 1,2,3 交換信息,儘管服務器 4 的編號大,但之前服務器 3 已經勝出,所以服務器 4 只能成爲小弟。
  5. 服務器 5 啓動,後面的邏輯同服務器 4 成爲小弟

48、Zookeeper 工作原理(原子廣播)

  1. Zookeeper 的核心是原子廣播,這個機制保證了各個 server 之間的同步。實現這個機制的協議叫做 Zab 協議。 Zab 協議有兩種模式,它們分別是恢復模式和廣播模式。
    2 .當服務啓動或者在領導者崩潰後, Zab 就進入了恢復模式,當領導者被選舉出來,且大多數 server 的完成了和 leader 的狀態同步以後,恢復模式就結束了。
  2. 狀態同步保證了 leader 和 server 具有相同的系統狀態
  3. 一旦 leader 已經和多數的 follower 進行了狀態同步後,他就可以開始廣播消息了,即進入廣播狀態。這時候當一個 server 加入 zookeeper 服務中,它會在恢復模式下啓動,發現 leader,並和 leader 進行狀態同步。待到同步結束,它也參與消息廣播。 Zookeeper服務一直維持在 Broadcast 狀態,直到 leader 崩潰了或者 leader 失去了大部分的followers 支持。
  4. 廣播模式需要保證 proposal 被按順序處理,因此 zk 採用了遞增的事務 id 號(zxid)來保證。所有的提議(proposal)都在被提出的時候加上了 zxid。
  5. 實現中 zxid 是一個 64 爲的數字,它高 32 位是 epoch 用來標識 leader 關係是否改變,每次一個 leader 被選出來,它都會有一個新的 epoch。低 32 位是個遞增計數。
  6. 當 leader 崩潰或者 leader 失去大多數的 follower,這時候 zk 進入恢復模式,恢復模式需要重新選舉出一個新的 leader,讓所有的 server 都恢復到一個正確的狀態

49、Znode 有四種形式的目錄節點

  1. PERSISTENT:持久的節點。
  2. EPHEMERAL: 暫時的節點。
  3. PERSISTENT_SEQUENTIAL:持久化順序編號目錄節點。
  4. EPHEMERAL_SEQUENTIAL:暫時化順序編號目錄節點。

擴展連接:加粗樣式更多請點擊這裏

博主公衆號程序員小羊 只發面試相關推文
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章