久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Zookeeper一致性協議Zab如何理解

216次閱讀
沒有評論

共計 4114 個字符,預計需要花費 11 分鐘才能閱讀完成。

這篇文章給大家介紹 Zookeeper 一致性協議 Zab 如何理解,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

zookeeper 是分布式協調系統,用來協調、同步多服務器之間的狀態,容錯能力強

一個應用要保證 HA,往往需要 N 個服務器(N 1) 提供服務,其中有 M 臺 master,N- M 臺 slave。這樣一臺掛了,另外 N - 1 臺也能提供服務。所以,數據也會備份成 N 份散布在這些服務器上。現在的問題變成了,如何管理這 N 臺服務器?如何在 master 節點失敗的時候重新選擇 master?如何保證所有服務器存儲的備份數據一致?

如果你碰到上面那些棘手的問題,zookeeper 剛好可以幫到你:

存儲公共配置信息

跟蹤所有進程運行狀態

集群中各節點的管理

master 選主

提供分布式同步支持(分布式鎖等功能)

上面列出的是官方提供的功能支持,還有很多其他功能等待挖掘。

當你的系統依賴 zookeeper 保證 HA 和一致性的時候,你肯定也好奇,zookeeper 本身是如何保證這兩個特性的。幕后功臣往往容易被忽視,其實它就是 Zookeeper 原子廣播協議(Zab 協議)。如果你了解過二階段提交、paxos 算法、raft 算法等大名鼎鼎的分布式一致性算法,Zab 肯定也不會陌生,因為他們要達到的目的相同,就是保證應用程序的 HA 和一致性。

為了讀懂后面的內容,有些術語需要了解:

Zab 的理論和實現并不完全一致。

實現是在理論的基礎之上做了一些優化手段,這些優化是在 zookeeper 不斷發展的過程中給加上的。我接下來的講解,也是參照這篇論文,以 zookeeper 3.3.3 的版本的實現為準,并用自己的語言總結。

理論中的協議

隨著系統啟動或者恢復,會經歷 Zab 協議中描述的如下四個階段

階段 0:Leader 選舉。每個 peer 從 Quorum peer 中選出自己心中的預備 leader

階段 1:發現。預備 leader 從 Quorum Follower 中發現最新的數據,并覆蓋自己的過期數據

階段 2:同步。預備 leader 采用二階段提交的方式將自己的最新數據同步給 Quorum Follower。完成這個步驟,預備 leader 就轉為正式 leader

階段 3:廣播。Leader 接受寫請求,并通過二階段提交的方式廣播給 Quorum Follower

之前我只是簡述了一下理論中的協議,然而理想很骨感,有很多需要改進或者妥協的地方。下面我會一一闡明:

階段 0 的選舉 leader 實際上很簡陋,只是“看對眼”了就選為預備 leader,所以預備 leader 的數據可能并非最新

預備 leader 數據過期,就需要用階段 1 來彌補,通過互相傳輸數據,來發現最新的數據,并完成預備 leader 的數據升級

更多的網絡間數據傳輸代表了更大的網絡開銷

協議實現

了解了理想的骨感之后,我們回歸現實。

真正 apache zookeeper 在實現上提出設想:優化 leader 選舉,直接選出最新的 Peer 作為預備 Leader,這樣就能將階段 0 和階段 1 合并,減少網絡上的開銷和多流程的復雜性

由圖可知,代碼實現上,協議被簡化為三個階段

快速選舉 Leader 階段:從 Quorum Peer 中選出數據最新的 peer 作為 leader

恢復階段:Leader 將數據同步給 Quorum Follower

廣播階段:Leader 接受寫請求,并廣播給 Quorum Follower

Talk is cheap.Show me the Code

這時 Linus 說過的一句話,無論語言多么有力,只有代碼才能真正展現作者的思想。之前我只是對是協議實現的三個階段做了一番簡述,只有代碼才能真正撥開 Zab 協議外面那層迷霧。(為了不浪費篇幅,這里采用偽代碼)

快速選舉 Leader 階段(FLE)

首先初始化一些數據

ReceivedVotes:投票箱,存儲投票節點以及當前投票信息

OutOfElection:存儲已經成為 Leader、Follower,不參與投票的節點信息,以及它的歷史投票信息

在選票中寫上自己的大名

send notification:發起選票通知,該節點會攜帶選票,進入目標節點的隊列中,相當于給自己投了一票,并毛遂自薦給其他人

如果當前節點處于選舉狀態,則它也會接到選票通知。它會從隊列中不斷輪詢節點,以便獲取選票信息(如果超時,則不斷放松超時時間,直至上限)。根據輪詢出來的發送節點的狀態,來做相應的處理。

election:如果發送節點的輪次(round)大于自己,說明自己的選舉信息過時,則更新自己的選舉輪次,清空投票箱,更新自己的選票內容,并將新的選票通知給其他節點;如果發送節點的輪次等于自己,并且投票內容比自己的更新,則只需要更新自己的選票,并通知給其他節點就行;如果發送節點的輪次小于自己,說明投票內容過期,沒有參考意義,直接忽略。所有未被忽略的選票,都會進入投票箱。最終根據選票箱中的結果,判斷當前節點的選票是不是占大多數,如果是就根據當前節點的選票選出 Leader

leading 或 following:發送節點輪次等于自己,說明發送節點還參與投票,如果發送節點是 Leading 或者它的選票在選票箱中占大多數,則直接完成選舉;如果發送節點已經完成選舉(輪次不同)或者它收集的選票較少,那么它的信息都會存放在 OutOfElection 中。當節點不斷完成選舉,OutOfElection 中數量逐漸變成 Quorum 時,就把 OutOfElection 當做投票箱,從中檢查發送節點的選票是否占多數,如果是就直接選出 Leader

恢復階段

經過 FLE,已經選出了日志中具有最新已提交的事務的節點作為預備 Leader。下面就分 Leader 和 Follower 兩個視角來介紹具體實現。

Leader 視角

首先,更新 lastZxid,將紀元 +1,計數清零,宣布改朝換代啦。然后在每次接收到 Follower 的數據同步請求時,都會將自己 lastZxid 反饋回去,表示所有 Follower 以自己的 lastZxid 為準。接下來,根據具體情況來判斷該如何將數據同步給 Follower

如果 Leader 的歷史提交事務比 Follower 的最新事務要新,說明 Follower 的數據有待更新。更新方式取決于,Leader 最早事務有沒有比 Follower 最新事務要新:如果前者更新,說明在 Leader 看來 Follower 所有記錄的事務都太過陳舊,沒有保留價值,這時只需要將 Leader 所有 history 發給 Follower 就行(響應 SNAP);如果后者更新,說明在 Leader 看來,Follower 從自己的 lastZxid 開始到 Leader 日志的最新事務,都需要同步,于是將這一部分截取并發送給 Follower(響應 DIFF)

如果 Leader 的歷史提交事務沒有 Follower 的最新事務新,說明 Follower 存在沒有提交的事務,這些事務都應該被丟棄(響應 TRUNC)

當 Follower 完成同步時,會發送同步 ack,當 Leader 收到 Quorum ack 時,表示數據同步階段大功告成,進入最后的廣播階段。

Follower 視角

通知 Leader,表示自己希望能同步 Leader 中的數據。

當收到 Leader 的拒絕響應時,說明 Leader 不承認自己作為 Follower,有可能該 Leader 并不可靠,于是開始重新開始 FLE

當收到 SNAP 或 DIFF 響應時,Follower 會同步 Leader 發送過來的事務

當收到 TRUNC 響應,Follower 會丟棄所有未完成的數據

當每個 Follower 完成上述的同步過程時,會發送 ack 給 Leader,并進入廣播階段。

廣播階段

進入到這個階段,說明所有數據完成同步,Leader 已經轉正。開始 zookeper 最常見的工作流程:廣播。

廣播階段是真正接受事務請求(寫請求)的階段,也代表了 zookeeper 正常工作階段。所有節點都能接受客戶端的寫請求,但是 Follower 會轉發給 Leader,只有 Leader 才能將這些請求轉化成事務,廣播出去。這個節點一樣有兩個角色,下面還是按照這兩個角色來講解。

Leader 視角:

Leader 必須經過 ready,才能接受寫請求。完成 ready 的 Leader 不斷接受寫請求,轉化成事務請求,廣播給 Quorum Follower。

當 Leader 接收到 ack 時,說明 Follower 完成相應處理,Leader 廣播提交請求,Follower 完成提交。

當發現新 Peer 請求作為 Follower 加入時,將自己的紀元、事務日志發送給該 Peer,以便它完成上述恢復階段的過程。收到該 Peer 的同步完成的 ack 時,Leader 會發送提交請求,以便 Peer 提交所有同步完成的事務。這時,該 Peer 轉正為 Follower,被 Leader 納入 Quorum Follower 中。

Follower 視角:

Follower 被發現是 Leading 狀態,則執行 ready 過程,用來接受寫請求。

當接受到 Leader 廣播過來的事務請求時,Follower 會將事務記錄在 history,并響應 ack。

當接收到 Leader 廣播過來的提交請求時,Follower 會檢查 history 中有沒有尚未提交的事務,如果有,需要等待之前的事務按照 FIFO 順序提交之后,才能提交本事務。

文章沒有介紹 Zookeeper 的使用,而是著重講解它的核心協議 Zab 的實現。正如文中提及,Zab 最早的設想和現在的實現并不相同,今日的實現是在 Zookeeper 不斷發展壯大的過程中不斷優化、改進而來的,也許早期的實現就是 yahoo 論文中構想的那樣。羅馬不是一日建成,任何人都不能指望一口吃個大胖子。如果 Zookeeper 剛開始就想著如何優化到極致,那反而會嚴重影響到這個項目本身的價值,因為它很可能還沒面試就被淘汰。

可以看出,過早優化是萬惡之源。但是同時,一個好的程序員也不會忘記需要優化的那部分,他會定位相應的代碼,然后針對性的修改。這也是 zookeeper 的開發者所做的。

關于 Zookeeper 一致性協議 Zab 如何理解就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-16發表,共計4114字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 类乌齐县| 班戈县| 南城县| 惠水县| 兴安县| 景泰县| 调兵山市| 荔波县| 河池市| 花垣县| 兰考县| 安庆市| 新源县| 贵港市| 乡宁县| 武宣县| 白沙| 远安县| 新竹市| 招远市| 边坝县| 广西| 全南县| 洞口县| 大足县| 合水县| 淄博市| 新津县| 都匀市| 乐至县| 益阳市| 连平县| 高密市| 固镇县| 长春市| 宁武县| 石屏县| 鄄城县| 安新县| 浪卡子县| 平度市|