ZooKeeper分佈式協調服務詳解

ClickHouse需要依賴ZooKeeper使用,本文對ZooKeeper做簡單介紹。

一、ZooKeeper定義

ZooKeeper譯名爲“動物園管理員”。各個子系統就好比動物園裏的動物,爲了使各個子系統能正常爲用戶提供統一的服務,必須需要一種機制來進行協調——這就是ZooKeeper。
ZooKeeper是一個開源的分佈式協調服務。分佈式應用程序可以基於 ZooKeeper實現如數據發佈/訂閱、負載均衡、命名服務、分佈式協調/通知、集羣管理、Master 選舉、配置維護,名字服務、分佈式同步、分佈式鎖和分佈式隊列等功能。原本是Apache Hadoop的一個組件,現在被拆分爲一個Hadoop的獨立子項目,在HBase(Hadoop的另外一個被拆分出來的子項目,用於分佈式環境下的超大數據量的DBMS)中也用到了ZooKeeper集羣。設計目的是爲了減輕分佈式應用程序所承擔的協調任務,通過選舉算法和集羣複製可以避免單點故障。

二、ZooKeeper特性

1 Zookeeper爲一個leader,多個follower組成的集羣
2 全局數據一致:每個server保存一份相同的數據副本,client無論連接到哪個server,數據都是一致的
3 分佈式讀寫,更新請求轉發,由leader實施
4 更新請求順序進行,來自同一個client的更新請求按其發送順序依次執行
5 數據更新原子性,一次數據更新要麼成功,要麼失敗
6 實時性,在一定時間範圍內,client能讀到最新數據

三、ZooKeeper的配置文件

Zookeeper 配置並不多,每個節點的配置文件zoo.cfg都是一樣的,只有myid文件不一樣。myid的值必須是zoo.cfg中server.的數值。

tickTime=2000 基本時間單元,代表發送心跳的間隔時間,單位毫秒
initLimit=30000 tickTime的倍數,follower和leader之間的最長心跳時間
syncLimit=10 tickTime的倍數,leader和follower之間發送消息,請求和應答的最大時間
dataDir=/zookeeper/data 持久化數據目錄
dataLogDir=/zookeeper/logs 日誌目錄,如果沒設定,默認和dataDir相同
clientPort=2181 監聽client連接的端口號
maxClientCnxns=2000 zookeeper最大連接
maxSessionTimeout=60000000 最大的會話超時時間
autopurge.snapRetainCount=10 保留snapshot的文件數目,默認3個
autopurge.purgeInterval=1 自動清理snapshot和事務日誌,清理頻率,單位是小時
globalOutstandingLimit=200 等待處理的最大請求數量,server端會拒絕client的請求,每一個client至少能有一個outstanding請求
preAllocSize=131072 日誌文件大小kb,切換快照生成日誌
snapCount=3000000 兩次事務快照之間可執行事務的次數,默認的配置值爲100000
leaderServes=yes leader是否接受client請求,默認爲yes即leader可以接受client的連接,當節點數爲>3時,建議關閉
standaloneEnabled=false 是否啓用獨立模式
server.1=IP01:2888:3888 服務編號,2888leader\follower傳輸信息端口,3888推舉端口
server.2=IP02:2888:3888 服務編號,2888leader\follower傳輸信息端口,3888推舉端口
server.3=IP03:2888:3888 服務編號,2888leader\follower傳輸信息端口,3888推舉端口
server.4=IP04:2888:3888:observer 服務編號,observer可以認爲是主的clone copy,不參與投票,縮短選舉時間
server.5=IP05:2888:3888:observer 服務編號,observer可以認爲是主的clone copy,不參與投票,縮短選舉時間

四、ZooKeeper數據結構

ZooKeeper路徑起始爲 /,子節點必須是絕對路徑,如同Unix系統中的文件路徑

五、ZooKeeper節點數據結構屬性

Zxid ZooKeeper狀態的每一次改變,都對應着一個遞增的Transaction id,該id稱爲zxid,全局唯一
Session 在client和server通信之前,首先需要建立連接,該連接稱爲session。連接建立後,如果發生連接超時、授權失敗或者顯式關閉連接,連接便處於CLOSED狀態,此時session結束。
persistent persistent節點不和特定的session綁定,不會隨着創建該節點的session的結束而消失,而是一直存在,除非該節點被顯式刪除。
ephemeral ephemeral節點是臨時性的,如果創建該節點的session結束了,該節點就會被自動刪除。使用-e參數指定創建ephemeral節點。
watch watch的意思是監聽感興趣的事件。在命令行中,以下幾個命令可以指定是否監聽相應的事件。
ticks 當在使用多機ZooKeeper服務時,服務器之間會使用ticks票據來定義事件(比如狀態上傳、會話超時、連接超時等等)的計時

[zk:localhost:2181(CONNECTED)5]stat /Apps/App1/SunApp1

cZxid = 0x700000005 節點創建時的zxid
ctime = Tue Oct 16 09:54:34 CST 2018 節點創建時的時間
mZxid = 0x700000005 節點最新一次更新發生時的zxid

mtime = Tue Oct 16 09:54:34 CST 2018

節點最新一次更新發生時的時間
pZxid = 0x735fb57ac 與該節點的子節點(或該節點)的最近一次創建或刪除的時間戳對應
cversion = 2 子節點版本號
dataVersion = 0 節點數據的版本號
aclVersion = 0 節點ACL(授權信息)的版本號
ephemeralOwner = 0x0

如果該節點是臨時節點,則值爲該節點綁定的session id;

如果ephemeralOwner值爲0,則該節點不是臨時節點

dataLength = 0 節點數據的字節數
numChildren = 2 子節點個數

六、ZooKeeper集羣

通常Zookeeper由2n+1臺servers組成,每個server都知道彼此的存在。每個server都維護的內存狀態鏡像以及持久化存儲的事務日誌和快照。爲了保證Leader選舉能過得到多數的支持,所以ZooKeeper集羣的數量一般爲奇數。對於2n+1臺server,只要有n+1臺(大多數)server可用,整個系統保持可用。

  1. 領導者(leader),負責進行投票的發起和決議,更新系統狀態。

  2. 學習者(learner),包括跟隨者(follower)和觀察者(observer)。

  3. follower用於接受客戶端請求並向客戶端返回結果,在選主過程中參與投票

  4. observer可以接受客戶端請求,將寫請求轉發給leader,但observer不參加投票過程,只同步leader的狀態,observer的目的是爲了擴展系統,提高讀取速度。

  5. 客戶端(client),請求發起方,讀請求直接由本地的複製數據庫提供數據。

七、ZooKeeper Server主要組件

  1. Request processor(請求處理器):包含多種接口。對每個請求,都是通過生產鏈的方式,一步步地進行處理。比如:

    PreRequestProcessor一般是放在處理鏈的起始部分的,它對請求做一些預處理,如檢查Session、檢查要操作的節點及其父節點是否存在、檢查客戶端是否有權限等;

    ProposalRequestProcessor用於向Follower發送Proposal,來完成ZAB算法;

    SyncRequestProcessor用於將請求持久化到磁盤中;

  2. Atomic Broadcast(ZAB協議):實現了主備模式下的系統架構,保持集羣中各個副本之間的數據一致性。ZAB協議定義了選舉(election)、發現(discovery)、同步(sync)、廣播(Broadcast)四個階段。

  3. Replicated database(複製的數據庫):是一個內存數據庫,包含整個數據樹。爲了可恢復,更新會被log到磁盤,並且在更新這個內存數據庫之前,先序列化到磁盤。

八、ZooKeeper 角色選舉

上面我們知道zookeeper集羣有三種角色:leader、follower、observer

一個zookeeper有三種狀態:

  • looking:選舉狀態,當前沒有leader;

  • leading:leader纔有的狀態;

  • following:follower纔有的狀態;

     

當集羣新建,或者主機死機,或者主機與一半或以上的從機失去聯繫後,都會觸發選擇新的主機操作。有兩種算法 fast paxos和 basic paxos,默認爲 fast paxos。

  1. observer角色不參與投票,可以縮短選舉時間。

  2. 每次選舉都要把選舉輪數加一,類似於zxid裏的epoch字段,防止不同輪次的選舉互相干擾。

  3. 每個進入looking狀態的節點,最開始投票給自己,然後把投票消息發給其它機器。內容爲<第幾輪投票,被投節點的zxid,被投節點的編號>。

  4. 其他looking狀態的節點收到後,首先判斷票是否有效,是否有效的方法爲看票的投票輪數和本地記載的投票輪數是否相等:

    4.1 如果比本地投票輪數的小,丟棄。

    4.2 如果比本地投票輪數的大,證明自己投票過期了,清空本地投票信息,更新投票輪數和結果爲收到的內容。通知其他所有節點新的投票方案。

    4.3 如果和本地投票輪數相等,按照投票的優先級比較收到的選票和自己投出去的選票。

    4.3.1 如果收到的優先級大,更新自己的投票爲對方發過來投票方案,把投票發出去。

    4.3.2 如果收到的優先級小,則忽略該投票。

    4.3.3 如果收到的優先級相等,則更新對應節點的投票。

  5. 每收集到一個投票後,查看已經收到的投票結果記錄列表,看是否有節點能夠達到一半以上的投票數。如果有達到,則終止投票,宣佈選舉結束,更新自身狀態。然後進行發現和同步階段。 否則繼續收集投票。

fast  paxos和basic paxos區別
這裏fast是主動推送出,只要結果有更新,就馬上同步給其他節點。其他節點可能還沒把自己的票通知給所有節點,就發現自己投的票優先級低,要更新投票,然後更新再重新通知給所有節點。
basic則要每一節點都詢問完,才能知道新結果,然後再去問其他節點新的選舉結果。
fast比basic快的地方,是一個節點不用和每個節點都交換投票信息後,才能知道自己的票是否要更新,可減少交互次數。

九、ZooKeeper命令

運行 ./zkCli.sh進入命令行工具

1、ls查看某個節點的子節點信息,絕對路徑

[zk:localhost:2181(CONNECTED)1] ls /

2、create創建一個新的znode

[zk:localhos:2181(CONNECTED)2] create /Apps "data"

3、get獲取znode信息

[zk:localhost:2181(CONNECTED)3] get /Apps

4、set更新znode內容

[zk:localhost:2181(CONNECTED)4] set /Apps "new"

5、stat獲取znode信息,同get

[zk:localhost:2181(CONNECTED)5] stat /Apps

6、delete刪除znode,子節點不被刪除

[zk:localhost:2181(CONNECTED)6] delete /Apps

7、rmr刪除znode及子節點

[zk:localhost:2181(CONNECTED)7] rmr /Apps

8、ls2是ls的增強版,比ls命令多輸出本節點信息

[zk:localhost:2181(CONNECTED)8] ls2 /Apps

9、listquota命令用於顯示配額

[zk:localhost:2181(CONNECTED)9] listquota /Apps

10、setquota命令用於設置節點個數以及數據長度的配額

[zk:localhost:2181(CONNECTED)10] setquota -n 2 /Apps

[zk:localhost:2181(CONNECTED)11] setquota -b 10 /Apps

11、delquota命令用於刪除配額

[zk:localhost:2181(CONNECTED)12] delquota -n 2

12、redo用於再次執行某個命令,配合history使用

[zk:localhost:2181(CONNECTED)13] redo id

13、addauth命令用於節點認證

[zk:localhost:2181(CONNECTED)14] addauth digest username:password

14、setAcl命令用於設置節點Acl

[zk:localhost:2181(CONNECTED)15] setAcl world:anyone:cdrwa

15、獲取節點的Acl

[zk:localhost:2181(CONNECTED)16] getAcl /Apps

16、sync命令用於強制同步

[zk:localhost:2181(CONNECTED)17] sync /Apps

17、printWatchers命令用於設置和顯示監視狀態

[zk:localhost:2181(CONNECTED)18] printwatches on

18、connect命令用於連接其他主機

[zk:localhost:2181(CONNECTED)19] connect host:port

 

 

 

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