您現在的位置是:首頁 > 手機遊戲首頁手機遊戲
Zookeeper原始碼級分析,精通底層原理
- 2023-01-25
zookeeper存在腦裂問題嗎
什麼是zookeeper?
他是一個分散式框架,主要解決分散式中經常遇到的資料管理問題,
例如:統一命名服務,叢集管理,分散式應用配置項
到官網下載壓縮包,下載下來就可以直接用了,非常方便。
Zookeeper 是一個數據庫,是一個擁有檔案系統的資料庫,是解決資料一致性的分散式資料庫,具有釋出和訂閱功能(註冊中心)。
Zk節點下面可以建立多個節點 get /node/test/ create/node11 111
那麼他是怎麼解決資料一致性問題呢
其實zk的靈魂就是ZAB協議
要從服務端的來去理解
Cap理論:
CAP理論指的是一個分散式系統最多隻能同時滿足一致性(Consistency)、可用性(Availability)和分割槽容錯性(Partition tolerance)這三項中的兩項。拿一個網上的圖來看看。
我麼先看資料庫。
強一致性:
任何一次讀都能讀到某個資料的最近一次寫的資料。
系統中的所有程序,看到的操作順序,都和全域性時鐘下的順序一致。
簡言之,在任意時刻,所有節點中的資料是一樣的。
最終一致性:
不保證在任意時刻任意節點上的同一份資料都是相同的,但是隨著時間的遷移,不同節點上的同一份資料總是在向趨同的方向變化。
簡單說,就是在一段時間後,節點間的資料會最終達到一致狀態
順序一致性:
系統的所有程序的順序一致,而且是合理的。即不需要和全域性時鐘下的順序一致,錯的話一起錯,對的話一起對。
Zk是怎樣實現最終一致性呢?
領導說;”今天下午3-4點”,大會議室開會,做一下未來規劃,收到請回復
而領導他會看多少人回覆了他這條通知,如果說,回覆的人太少,他可能會再次進行通知,如果回覆的人比較多,他就放心了,他並不會統計是不是所有人都回復了
等到下午3點,所有同事一起做未來規劃。
這個就是過半機制(請求->等待回覆->提交做事情 兩階段提交)prepare,預提交,等待ack ,commit
領導者選舉:投票,投給自己,交流,比較,選出leader
統計。
話說在分散式系統中一般都要使用主從系統架構模型,指的是一臺leader伺服器負責外部客戶端的寫請求。然後其他的都是follower伺服器。leader伺服器將客戶端的寫操作資料同步到所有的follower節點中。
就這樣,客戶端傳送來的寫請求,全部給Leader,然後leader再轉給Follower。這時候需要解決兩個問題:
(1)leader伺服器是如何把資料更新到所有的Follower的。
(2)Leader伺服器突然間失效了,怎麼辦?
因此ZAB協議為了解決上面兩個問題,設計了兩種模式:
(1)訊息廣播模式:把資料更新到所有的Follower
(2)崩潰恢復模式:Leader發生崩潰時,如何恢復
Zk資料儲存結構:
dataTree
二叉樹機結構:傳送命令 create/node 1
加到dataTree中 持久化到磁盤裡中,如果機器掛掉了,記憶體的資料丟失,就儲存不到磁碟中去了。
應該先持久化,先把請求進行持久化,再去構建DataTree
有日誌來做記錄,其實是打快照的原理。日誌+快照
事務性請求(create set delete)和非事務性請求(get exist(),不需要記錄日誌)
日誌中有一個zkid 每一個zk服務都有一個zkid 比較zkid最大的 選舉他。
Zk如何解決腦裂問題:
我們把原始碼down下來,
我們以原始碼的形式啟動zk服務
叢集,連其他伺服器一直心跳去連線
官方定義:當一個叢集的不同部分在同一時間都認為自己是活動的時候,我們就可以將這個現象稱為腦裂症狀。通俗的說,就是比如當你的 cluster 裡面有兩個結點,它們都知道在這個 cluster 裡需要選舉出一個 master。那麼當它們兩之間的通訊完全沒有問題的時候,就會達成共識,選出其中一個作為 master。但是如果它們之間的通訊出了問題,那麼兩個結點都會覺得現在沒有 master,所以每個都把自己選舉成 master。於是 cluster 裡面就會有兩個 master
ZooKeeper每個節點都嘗試註冊一個象徵master的臨時節點,其他沒有註冊成功的則成為slaver,並且透過watch機制監控著master所建立的臨時節點,Zookeeper透過內部心跳機制來確定master的狀態,一旦master出現意外Zookeeper能很快獲悉並且通知其他的slaver,其他slaver在之後作出相關反應。這樣就完成了一個切換。
假死:
這種模式也是比較通用的模式,基本大部分都是這樣實現的,但是這裡面有個很嚴重的問題,如果注意不到會導致短暫的時間內系統出現腦裂,因為心跳出現超時可能是master掛了,但是也可能是master,zookeeper之間網路出現了問題,也同樣可能導致。這種情況就是假死,master並未死掉,但是與ZooKeeper之間的網路出現問題導致Zookeeper認為其掛掉瞭然後通知其他節點進行切換,這樣slaver中就有一個成為了master,但是原本的master並未死掉,這時候client也獲得master切換的訊息,但是仍然會有一些延時,zookeeper需要通訊需要一個一個通知,這時候整個系統就很混亂可能有一部分client已經通知到了連線到新的master上去了,有的client仍然連線在老的master上如果同時有兩個client需要對master的同一個資料更新並且剛好這兩個client此刻分別連線在新老的master上,就會出現很嚴重問題。
解決方案:
1、新增心跳線。
原來兩個namenode之間只有一條心跳線路,此時若斷開,則接收不到心跳報告,判斷對方已經死亡。此時若有2條心跳線路,一條斷開,另一條仍然能夠接收心跳報告,能保證叢集服務正常執行。2條心跳線路同時斷開的可能性比1條心跳線路斷開的小得多。再有,心跳線路之間也可以HA(高可用),這兩條心跳線路之間也可以互相檢測,若一條斷開,則另一條馬上起作用。正常情況下,則不起作用,節約資源。
2、啟用磁碟鎖。
由於兩個active會爭搶資源,導致從節點不知道該連線哪一臺namenode,可以使用磁碟鎖的形式,保證叢集中只能有一臺namenode獲取磁碟鎖,對外提供服務,避免資料錯亂的情況發生。但是,也會存在一個問題,若該namenode節點宕機,則不能主動釋放鎖,那麼其他的namenode就永遠獲取不了共享資源。因此,在HA上使用“
智慧鎖
”就成為了必要措施。“智慧鎖”是指active的namenode檢測到了心跳線全部斷開時才啟動磁碟鎖,正常情況下不上鎖。保證了假死狀態下,仍然只有一臺namenode的節點提供服務。
3、設定仲裁機制
腦裂導致的後果最主要的原因就是從節點不知道該連線哪一臺namenode,此時如果有一方來決定誰留下,誰放棄就最好了。因此出現了仲裁機制,比如提供一個參考的IP地址,當出現腦裂現象時,雙方接收不到對方的心跳機制,但是能同時ping參考IP,如果有一方ping不通,那麼表示該節點網路已經出現問題,則該節點需要自行退出爭搶資源的行列,或者更好的方法是直接強制重啟,這樣能更好的釋放曾經佔有的共享資源,將服務的提供功能讓給功能更全面的namenode節點。