大資料3_04_zookeeper概述和內部原理

最佳第六六六人發表於2020-10-19

1 Zookeeper

(1)概述

zookeeper是開源的、分散式的、為分散式應用提供協調服務的Apache專案。

  • 是一個基於觀察者模式設計的分散式服務管理框架。
  • 負責儲存和管理大家都關心的資料,然後接受觀察者的註冊,一旦資料狀態變化,zookeeper就負責通知在zookeeper上註冊的觀察者做出相應反應。

1596120102029

(2)特點

1596120250931

  • Zookeeper:一個領導者(Leader),多個跟隨著(Follower)組成的叢集。
  • 叢集只有半數以上節點存活,Zookeeper就能正常服務!(必須是>半數)
  • 全域性資料一樣,每個Server都有一份資料副本。
  • 更新請求順序進行,來自同一個Client的更新請求按傳送順序依次進行。
  • 資料更新原子性,一次資料要麼成功,要麼失敗。
  • 實時性,在一定時間範圍內,Client能讀到最新資料。(每隔一定時間進行一次備份)

(3)資料結構

1596120629475

需要注意i的是每個znode預設儲存1M的資料。

(4)Zookeeper下載地址

https://zookeeper.apache.org/

5 ZooKeeper內部原理

5.1 節點的型別

節點有四種型別

  • 永久、無序號節點:預設;PERSISTENT
  • 永久、帶序號節點:-s;PERSISTENT_SEQUENTIAL
  • 臨時、無序號節點:-e;EPHEMERAL
  • 臨時、有序號節點:-es;EPHEMERAL_SEQUENTIAL

-s,會建立帶順序標識的節點,預設是從0000000000開始,自增長。增長的序號只在平級目錄下生效。在其子目錄下建立節點,也會從0000000000開始自增長。

-e,臨時節點,是在quit退出客戶端後,節點消失。臨時節點還是永久節點的標誌是:stat下的ephemeralOwner,如果是0x0則是永久節點,如果是0x20001353ddb0007則是臨時節點。

5.2 Stat結構體

# 輸出結果
cZxid = 0x90000002a		//建立節點的事務zxid
ctime = Mon Oct 19 17:42:08 CST 2020	//節點被建立的時間
mZxid = 0x900000031		//最後更新節點的事務zxid
mtime = Mon Oct 19 17:45:18 CST 2020	//最後更新節點的時間
pZxid = 0x90000002b		//最後更新的子節點的zxid
cversion = 1	//子節點變化號
dataVersion = 1		//資料變化號
aclVersion = 0		//訪問控制列表的變化號
ephemeralOwner = 0x0	//0x0表示永久節點,臨時節點:ephemeralOwner = 0x20001353ddb0007
dataLength = 8		//節點的資料長度
numChildren = 1		//子節點的數量

5.3 監聽器原理

(1)首先在ZKClient類中有一個主執行緒

(2)在主執行緒中new ZooKeeper();會建立兩個執行緒,一個負責網路通訊(connect),一個負責監聽(listener)

(3)通過connect執行緒將註冊的監聽事件傳送給ZooKeeper

(4)在ZooKeeper的註冊監聽列表中將註冊的監聽事件新增到列表中

(5)ZooKeeper監聽到有資料或路徑,發生變化就會將該訊息傳送給listener執行緒

(6)listener執行緒內部呼叫了process()

process()就是自己寫的監聽器,有兩處建立監聽器:

  • 在new ZooKeeper(String connectname, int sessionTimeout, Watcher watcher),要建立監聽器
  • 在運算元據,目錄的時候如:getChildren(String path, Watcher watcher),可以使用建立zookeeper的時候預設的監聽器,也可以重新自定義監聽器。

image-20201019191848246

5.4 選舉機制

(1)半數機制:叢集中半數以上的機器存活,叢集可用。

一臺機器,叢集不可用;兩臺機器,雖然叢集可用,二者myid大的為leader,但是叢集掛一臺也就不能用了,兩臺也不可用。

zookeeper叢集最少存在三臺叢集。zookeeper適合安裝奇數太機器。

(2)選舉過程:(5臺伺服器)

image-20201019193554795

  • Server1啟動,發起一起選舉,伺服器1投自己一票,然後會嘗試與其他伺服器通訊(3888),連線不到,此時未達到半數原則,則選舉失敗,保持LOOKING狀態。
  • Server2啟動,發起一起選舉,伺服器1伺服器2分別投自己一票,然後交換選舉資訊(2888),Server1發現伺服器2的myid更大,更改選票投給server2,此時Server2兩票,Server1零票,沒有達到半數原則,選舉失敗,兩者都保持LOOKING狀態。
  • Server3啟動,發起一起選舉,大家各自投自己一票,然後交換選舉資訊,Server1和Server2發現伺服器3的myid更大,更改選票給Server3,此時Server3三票,達到半數原則,選舉成功,更改狀態位LEADING,Server1和Server2更改狀態為FOLLOWING。
  • Server4啟動,發起一起選舉,此時伺服器123已經不是LOOKING狀態,不會更改選票資訊,則更改為FOLLOWING。
  • Server5同理。

5.5 寫資料流程

image-20201019195042182

(1)Client會向Server1寫資料,傳送一個寫請求。

(2)如果Server1不是Leader,那麼Server1會將寫請求,傳送給Leader節點,Leader收到寫請求後,會將該請求廣播給各個Server,各個Server會將該寫請求加入待寫佇列,並向Leader傳送成功資訊。

(3)如果Leader接收到半數以上的成功資訊,就說明該寫操作可執行,然後會給各個Server傳送資訊,Server收到後會落實訊息佇列中的寫操作。

問題1:Server怎樣判斷自己是否同意執行該請求呢?

判斷當前的zxid和請求的zxid,如果當前的zxid>請求的,那麼就不執行。

問題2:如果有一半以上的不回覆Leader的資訊呢?

就不執行該寫操作了,就說明該Leader的資料太落後了,Leader會自殺,然後重新選舉Leader,然後同步Leader的資料。

問題3:如果叢集中有一個Server不同意該寫操作呢?

那麼該Server就自殺,然後重新從Leader上同步資料。

問題4:什麼時候會發生半數以上不同意Leader請求的情況呢?

網路丟包等原因。

代表機制:(為了提高叢集的寫效能)

使用條件:zookeeper叢集特別大

image-20201019200915749

相關文章