ZooKeeper的初識(Zookeeper基本知識,ZooKeeper shell,ZooKeeper數據模型 ,ZooKeeper Watcher 監聽機制,ZooKeeper選舉機制)

Zookeeper基本知識

 

      Zookeeper集羣搭建

     Zookeeper集羣搭建指的是ZooKeeper分佈式模式安裝。通常由2n+1臺servers組成。這是因爲爲了保證Leader選舉(基於Paxos算法的實現)能過得到多數的支持,所以ZooKeeper集羣的數量一般爲奇數。

Zookeeper運行需要java環境,所以需要提前安裝jdk。對於安裝leader+follower模式的集羣,大致過程如下:

  1. 配置主機名稱到IP地址映射配置
  2. 修改ZooKeeper配置文件
  3. 遠程複製分發安裝文件
  4. 設置myid
  5. 啓動ZooKeeper集羣

如果要想使用Observer模式,可在對應節點的配置文件添加如下配置:

peerType=observer  

其次,必須在配置文件指定哪些節點被指定爲Observer,如:

server.1:node-1:2181:3181:observer  

下載安裝zookeeper見:https://blog.csdn.net/weixin_44036154/article/details/103476915

 

     Zookeeper概述

     Zookeeper是一個分佈式協調服務的開源框架。主要用來解決分佈式集羣中應用系統的一致性問題。

ZooKeeper本質上是一個分佈式的小文件存儲系統。提供基於類似於文件系統的目錄樹方式的數據存儲,並且可以對樹中的節點進行有效管理。從而用來維護和監控你存儲的數據的狀態變化。通過監控這些數據狀態的變化,從而可以達到基於數據的集羣管理。

 

     Zookeeper特性

  1. 全局數據一致:集羣中每個服務器保存一份相同的數據副本,client無論連接到哪個服務器,展示的數據都是一致的,這是最重要的特徵;
  2. 可靠性:如果消息被其中一臺服務器接受,那麼將被所有的服務器接受。
  3. 順序性:包括全局有序和偏序兩種:全局有序是指如果在一臺服務器上消息a在消息b前發佈,則在所有Server上消息a都將在消息b前被髮布;偏序是指如果一個消息b在消息a後被同一個發送者發佈,a必將排在b前面。
  4. 數據更新原子性:一次數據更新要麼成功(半數以上節點成功),要麼失敗,不存在中間狀態;
  5. 實時性:Zookeeper保證客戶端將在一個時間間隔範圍內獲得服務器的更新信息,或者服務器失效的信息。

 

    Zookeeper集羣角色

Leader: 

Zookeeper集羣工作的核心

事務請求(寫操作)的唯一調度和處理者,保證集羣事務處理的順序性;

集羣內部各個服務器的調度者。

對於create,setData,delete等有寫操作的請求,則需要統一轉發給leader處理,leader需要決定編號、執行操作,這個過程稱爲一個事務。

Follower:

處理客戶端非事務(讀操作)請求,轉發事務請求給Leader;

參與集羣Leader選舉投票。

此外,針對訪問量比較大的zookeeper集羣,還可新增觀察者角色。

Observer:

觀察者角色,觀察Zookeeper集羣的最新狀態變化並將這些狀態同步過來,其對於非事務請求可以進行獨立處理,對於事務請求,則會轉發給Leader服務器進行處理。

不會參與任何形式的投票只提供非事務服務,通常用於在不影響集羣事務處理能力的前提下提升集羣的非事務處理能力。

 

ZooKeeper shell

     開啓/關閉zookeeper:

           zkServer.sh start/stop

     客戶端連接

          運行 zkCli.sh –server ip   進入命令行工具。

           輸入help,輸出zk shell提示:

 

shell基本操作

 

   創建節點

create [-s] [-e] path data acl

其中,-s或-e分別指定節點特性,順序或臨時節點,若不指定,則表示持久節點;acl用來進行權限控制。

創建順序節點:創建一個順序節點,節點名是test,節點內容爲123   --->create -s /test 123

創建臨時節點:創建一個臨時節點,節點名爲test-temp,節點內容爲123tmp --->create -e /test-temp 123tmp

創建永久節點:創建永久節點test-p ,節點內容爲123p --->create /test-p 123p

創建子節點:創建test-p的子節點,節點名爲test-c,內容爲123c --->create /test-p/test-c 123c

 

讀取節點

與讀取相關的命令有ls 命令和get 命令,ls命令可以列出Zookeeper指定節點下的所有子節點,只能查看指定節點下的第一級的所有子節點;get命令可以獲取Zookeeper指定節點的數據內容和屬性信息。

ls path [watch]

get path [watch]

ls2 path [watch]

 

更新節點

set path data [version]

data就是要更新的新內容,version表示數據版本。

現在dataVersion已經變爲1了,表示進行了更新。

 

刪除節點

delete path [version]

若刪除節點存在子節點,那麼無法刪除該節點,必須先刪除子節點,再刪除父節點。

Rmr path

可以遞歸刪除節點。

 

quota

setquota -n|-b val path  對節點增加限制。

n:表示子節點的最大個數

b:表示數據值的最大長度

val:子節點最大個數或數據值的最大長度

path:節點路徑

(雖然說設定了最大的子節點個數或數據值的最大長度,但是超出時不會阻止,只會在日誌裏面抱一個warning警告)

listquota path  列出指定節點的quota

子節點個數爲2,數據長度-1表示沒限制

delquota [-n|-b] path  刪除quota

其他命令

history : 列出命令歷史

redo:該命令可以重新執行指定命令編號的歷史命令,命令編號可以通過history查看

 

ZooKeeper數據模型

      ZooKeeper的數據模型,在結構上和標準文件系統的非常相似,擁有一個層次的命名空間,都是採用樹形層次結構,ZooKeeper樹中的每個節點被稱爲—Znode。和文件系統的目錄樹一樣,ZooKeeper樹中的每個節點可以擁有子節點。但也有不同之處:

  1. Znode兼具文件和目錄兩種特點。既像文件一樣維護着數據、元信息、ACL、時間戳等數據結構,又像目錄一樣可以作爲路徑標識的一部分,並可以具有子Znode。用戶對Znode具有增、刪、改、查等操作(權限允許的情況下)。
  2. Znode具有原子性操作,讀操作將獲取與節點相關的所有數據,寫操作也將替換掉節點的所有數據。另外,每一個節點都擁有自己的ACL(訪問控制列表),這個列表規定了用戶的權限,即限定了特定用戶對目標節點可以執行的操作。
  3. Znode存儲數據大小有限制。ZooKeeper雖然可以關聯一些數據,但並沒有被設計爲常規的數據庫或者大數據存儲,相反的是,它用來管理調度數據,比如分佈式應用中的配置文件信息、狀態信息、彙集位置等等。這些數據的共同特性就是它們都是很小的數據,通常以KB爲大小單位。ZooKeeper的服務器和客戶端都被設計爲嚴格檢查並限制每個Znode的數據大小至多1M,當時常規使用中應該遠小於此值。
  4. Znode通過路徑引用,如同Unix中的文件路徑。路徑必須是絕對的,因此他們必須由斜槓字符來開頭。除此以外,他們必須是唯一的,也就是說每一個路徑只有一個表示,因此這些路徑不能改變。在ZooKeeper中,路徑由Unicode字符串組成,並且有一些限制。字符串"/zookeeper"用以保存管理信息,比如關鍵配額信息。

 

    數據結構圖

        

圖中的每個節點稱爲一個Znode。 每個Znode由3部分組成:

① stat:此爲狀態信息, 描述該Znode的版本, 權限等信息

② data:與該Znode關聯的數據

③ children:該Znode下的子節點

 

節點類型

Znode有兩種,分別爲臨時節點永久節點

節點的類型在創建時即被確定,並且不能改變。

臨時節點:該節點的生命週期依賴於創建它們的會話。一旦會話結束,臨時節點將被自動刪除,當然可以也可以手動刪除。臨時節點不允許擁有子節點
永久節點:該節點的生命週期不依賴於會話,並且只有在客戶端顯示執行刪除操作的時候,他們才能被刪除。

Znode還有一個序列化的特性,如果創建的時候指定的話,該Znode的名字後面會自動追加一個不斷增加的序列號。序列號對於此節點的父節點來說是唯一的,這樣便會記錄每個子節點創建的先後順序。它的格式爲“%10d”(10位數字,沒有數值的數位用0補充,例如“0000000001”)。

這樣便會存在四種類型的Znode節點,分別對應:

PERSISTENT:永久節點

EPHEMERAL:臨時節點

PERSISTENT_SEQUENTIAL:永久節點、序列化

EPHEMERAL_SEQUENTIAL:臨時節點、序列化

 

節點屬性

每個znode都包含了一系列的屬性,通過命令get,可以獲得節點的屬性。

 

dataVersion:數據版本號,每次對節點進行set操作,dataVersion的值都會增加1(即使設置的是相同的數據),可有效避免了數據更新時出現的先後順序問題。

cversion :子節點的版本號。當znode的子節點有變化時,cversion 的值就會增加1。

cZxid :Znode創建的事務id。

mZxid :Znode被修改的事務id,即每次對znode的修改都會更新mZxid。

對於zk來說,每次的變化都會產生一個唯一的事務id,zxid(ZooKeeper Transaction Id)。通過zxid,可以確定更新操作的先後順序。例如,如果zxid1小於zxid2,說明zxid1操作先於zxid2發生,zxid對於整個zk都是唯一的,即使操作的是不同的znode。

ctime:節點創建時的時間戳.

mtime:節點最新一次更新發生時的時間戳.

ephemeralOwner:如果該節點爲臨時節點, ephemeralOwner值表示與該節點綁定的session id. 如果不是, ephemeralOwner值爲0.

在client和server通信之前,首先需要建立連接,該連接稱爲session。連接建立後,如果發生連接超時、授權失敗,或者顯式關閉連接,連接便處於CLOSED狀態, 此時session結束。

 

ZooKeeper Watcher(監聽機制)

        ZooKeeper提供了分佈式數據發佈/訂閱功能,一個典型的發佈/訂閱模型系統定義了一種一對多的訂閱關係,能讓多個訂閱者同時監聽某一個主題對象,當這個主題對象自身狀態變化時,會通知所有訂閱者,使他們能夠做出相應的處理。

ZooKeeper中,引入了Watcher機制來實現這種分佈式的通知功能。ZooKeeper允許客戶端向服務端註冊一個Watcher監聽,當服務端的一些事件觸發了這個Watcher,那麼就會向指定客戶端發送一個事件通知來實現分佈式的通知功能。

觸發事件種類很多,如:節點創建,節點刪除,節點改變,子節點改變等。

總的來說可以概括Watcher爲以下三個過程:客戶端向服務端註冊Watcher、服務端事件發生觸發Watcher、客戶端回調Watcher得到觸發事件情況

 

      Watch機制特點

一次性觸發 

事件發生觸發監聽,一個watcher event就會被髮送到設置監聽的客戶端,這種效果是一次性的,後續再次發生同樣的事件,不會再次觸發。

事件封裝

ZooKeeper使用WatchedEvent對象來封裝服務端事件並傳遞。

WatchedEvent包含了每一個事件的三個基本屬性:

通知狀態(keeperState)事件類型(EventType)節點路徑(path)

event異步發送  

watcher的通知事件從服務端發送到客戶端是異步的。

先註冊再觸發

Zookeeper中的watch機制,必須客戶端先去服務端註冊監聽,這樣事件發送纔會觸發監聽,通知給客戶端。

 

   通知狀態和事件類型

    同一個事件類型在不同的通知狀態中代表的含義有所不同,下表列舉了常見的通知狀態和事件類型。

 

其中連接狀態事件(type=None, path=null)不需要客戶端註冊,客戶端只要有需要直接處理就行了。

 

Shell 客戶端設置watcher

設置節點數據變動監聽:

通過另一個客戶端更改節點數據:

此時設置監聽的節點收到通知:

 

ZooKeeper選舉機制

      zookeeper默認的算法是FastLeaderElection,採用投票數大於半數則勝出的邏輯。

    概念

服務器ID

比如有三臺服務器,編號分別是1,2,3。

編號越大在選擇算法中的權重越大。

選舉狀態

LOOKING,競選狀態。

FOLLOWING,隨從狀態,同步leader狀態,參與投票。

OBSERVING,觀察狀態,同步leader狀態,不參與投票。

LEADING,領導者狀態。

數據ID

服務器中存放的最新數據version。

值越大說明數據越新,在選舉算法中數據越新權重越大。

邏輯時鐘

也叫投票的次數,同一輪投票過程中的邏輯時鐘值是相同的。每投完一次票這個數據就會增加,然後與接收到的其它服務器返回的投票信息中的數值相比,根據不同的值做出不同的判斷。

 

   全新集羣選舉

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

 

  非全新集羣選舉

對於運行正常的zookeeper集羣,中途有機器down掉,需要重新選舉時,選舉過程就需要加入數據ID服務器ID邏輯時鐘

數據ID:數據新的version就大,數據每次更新都會更新version。

服務器ID:就是我們配置的myid中的值,每個機器一個。

邏輯時鐘:這個值從0開始遞增,每次選舉對應一個值。 如果在同一次選舉中,這個值是一致的。

這樣選舉的標準就變成:

1、邏輯時鐘小的選舉結果被忽略,重新投票;

2、統一邏輯時鐘後,數據id大的勝出;

3、數據id相同的情況下,服務器id大的勝出;

根據這個規則選出leader。

發佈了76 篇原創文章 · 獲贊 164 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章