目錄
- ZooKeeper 是什么?
- Zookeeper的用途,使用場景
- zookeeper集群
- zookeeper集群角色
- zookeeper集群作業原理
- zookeeper集群選舉的原理
- zookeeper watcher機制
- 客戶端注冊 Watcher
- 服務端觸發 Watcher
- zookeeper宕機處理
ZooKeeper 是什么?
ZooKeeper 是一個開源的分布式協調服務,它是一個為分布式應用提供一致性服務的軟體,
Zookeeper的用途,使用場景
分布式應用程式可以基于 Zookeeper 實作諸如資料發布/訂閱、負載均衡、命名服務、分布式協調/通知、集群管理、Master 選舉、分布式鎖和分布式佇列等功能,
ZooKeeper 的目標就是封裝好復雜易出錯的關鍵服務,將簡單易用的介面和性能高效、功能穩定的系統提供給用戶,
zookeeper集群
zookeeper集群架構圖
zookeeper集群角色
| zookeeper集群角色 | ||
|---|---|---|
| 角色 | 描述 | |
| 領導者(leader) | 領導負責投票發起和決議,更新集群狀態 | |
| 學習者(Learner) | 跟隨者(follower) | follower用于接收客戶端請求并向客戶端回傳結果,參與選舉投票 |
| 觀察者(observer) | observer接收客戶端連接,將請求轉給leader,不參與投票、只同步leader狀態,存在是為了擴展集群回應速度 | |
| 客戶端(client) | 請求發起方 | |
zookeeper集群作業原理
Zookeeper的核心是原子廣播,這個機制保證了各個Server之間的同步,實作這個機制的協議叫做Zab協議,
Zab協議有兩種模式,它們分 別是恢復模式(選主)和廣播模式(同步),當服務啟動或者在領導者崩潰后,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和 leader的狀態同步以后,恢復模式就結束了,恢復模式結束后,Zab進入廣播模式,狀態同步保證了leader和Server具有相同的系統狀態,
為了保證事務的順序一致性,zookeeper采用了遞增的事務id號(zxid)來標識事務,所有的提議(proposal)都在被提出的時候加上 了zxid,實作中zxid是一個64位的數字,它高32位是epoch用來標識leader關系是否改變,每次一個leader被選出來,它都會有一個 新的epoch,標識當前屬于那個leader的統治時期,低32位用于遞增計數,
每個Server在作業程序中有三種狀態:
-
LOOKING:當前Server不知道leader是誰,正在搜尋
-
LEADING:當前Server即為選舉出來的leader
-
FOLLOWING:leader已經選舉出來,當前Server與之同步
zookeeper集群選舉的原理
半數通過
當leader崩潰或者leader失去大多數的follower,這時候zk進入恢復模式,恢復模式需要重新選舉出一個新的leader,讓所有的 Server都恢復到一個正確的狀態,
Zk的選舉演算法有兩種:一種是基于basic paxos實作的,另外一種是基于fast paxos演算法實作的,系統默認的選舉演算法為fast paxos,
-
A提案說,我要選自己,B你同意嗎?C你同意嗎?B說,我同意選A;C說,我同意選A,(注意,這里超過半數了,其實在現實世界選舉已經成功了,但是計算機世界是很嚴格,另外要理解演算法,要繼續模擬下去,)
-
接著B提案說,我要選自己,A你同意嗎;A說,我已經超半數同意當選,你的提案無效;C說,A已經超半數同意當選,B提案無效,
-
接著C提案說,我要選自己,A你同意嗎;A說,我已經超半數同意當選,你的提案無效;B說,A已經超半數同意當選,C的提案無效,
-
選舉已經產生了Leader,后面的都是follower,只能服從Leader的命令,而且這里還有個小細節,就是其實誰先啟動誰當頭,
zookeeper watcher機制
Zookeeper 允許客戶端向服務端的某個 Znode 注冊一個 Watcher 監聽,當服務端的一些指定事件觸發了這個 Watcher,服務端會向指定客戶端發送一個事件通知來實作分布式的通知功能,然后客戶端根據 Watcher 通知狀態和事件型別做出業務上的改變,
作業機制:
-
(1)客戶端注冊 watcher
-
(2)服務端處理 watcher
-
(3)客戶端回呼 watcher
Watcher 特性總結:
- (1)一次性
無論是服務端還是客戶端,一旦一個 Watcher 被 觸 發 ,Zookeeper 都會將其從相應的存盤中移除,這樣的設計有效的減輕了服務端的壓力,不然對于更新非常頻繁的節點,服務端會不斷的向客戶端發送事件通知,無論對于網路還是服務端的壓力都非常大,
- (2)客戶端串行執行
客戶端 Watcher 回呼的程序是一個串行同步的程序,
-
(3)輕量
-
3.1、Watcher 通知非常簡單,只會告訴客戶端發生了事件,而不會說明事件的具體內容,
-
3.2、客戶端向服務端注冊 Watcher 的時候,并不會把客戶端真實的 Watcher 物件物體傳遞到服務端,僅僅是在客戶端請求中使用 boolean 型別屬性進行了標記,
-
-
(4)watcher event 異步發送 watcher 的通知事件從 server 發送到 client 是異步的,這就存在一個問題,不同的客戶端和服務器之間通過 socket 進行通信,由于網路延遲或其他因素導致客戶端在不通的時刻監聽到事件,由于 Zookeeper 本身提供了 ordering guarantee,即客戶端監聽事件后,才會感知它所監視 znode發生了變化,所以我們使用 Zookeeper 不能期望能夠監控到節點每次的變化,Zookeeper 只能保證最終的一致性,而無法保證強一致性,
-
(5)注冊 watcher getData、exists、getChildren
-
(6)觸發 watcher create、delete、setData
-
(7)當一個客戶端連接到一個新的服務器上時,watch 將會被以任意會話事件觸發,當與一個服務器失去連接的時候,是無法接收到 watch 的,而當 client 重新連接時,如果需要的話,所有先前注冊過的 watch,都會被重新注冊,通常這是完全透明的,只有在一個特殊情況下,watch 可能會丟失:對于一個未創建的 znode的 exist watch,如果在客戶端斷開連接期間被創建了,并且隨后在客戶端連接上之前又洗掉了,這種情況下,這個 watch 事件可能會被丟失,
客戶端注冊 Watcher
-
(1)呼叫 getData()/getChildren()/exist()三個 API,傳入 Watcher 物件
-
(2)標記請求 request,封裝 Watcher 到 WatchRegistration
-
(3)封裝成 Packet 物件,發服務端發送 request
-
(4)收到服務端回應后,將 Watcher 注冊到 ZKWatcherManager 中進行管理
-
(5)請求回傳,完成注冊,
服務端觸發 Watcher
- (1)服務端接收 Watcher 并存盤
接收到客戶端請求,處理請求判斷是否需要注冊 Watcher,需要的話將資料節點的節點路徑和 ServerCnxn(ServerCnxn 代表一個客戶端和服務端的連接,實作了 Watcher 的 process 介面,此時可以看成一個 Watcher 物件)存盤在WatcherManager 的 WatchTable 和 watch2Paths 中去,
- (2)Watcher 觸發
以服務端接收到 setData() 事務請求觸發 NodeDataChanged 事件為例:-
2.1 封裝 WatchedEvent
將通知狀態(SyncConnected)、事件型別(NodeDataChanged)以及節點路徑封裝成一個 WatchedEvent 物件 -
2.2 查詢 Watcher
從 WatchTable 中根據節點路徑查找 Watcher -
2.3 沒找到;說明沒有客戶端在該資料節點上注冊過 Watcher
-
2.4 找到;提取并從 WatchTable 和 Watch2Paths 中洗掉對應 Watcher(從這里可以看出 Watcher 在服務端是一次性的,觸發一次就失效了)
-
- (3)呼叫 process 方法來觸發 Watcher
這里 process 主要就是通過 ServerCnxn 對應的 TCP 連接發送 Watcher 事件通知,
zookeeper宕機處理
Zookeeper 本身也是集群,推薦配置不少于 3 個服務器,Zookeeper 自身也要保證當一個節點宕機時,其他節點會繼續提供服務,
如果是一個 Follower 宕機,還有 2 臺服務器提供訪問,因為 Zookeeper 上的資料是有多個副本的,資料并不會丟失;如果是一個 Leader 宕機,Zookeeper 會選舉出新的 Leader,
ZK 集群的機制是只要超過半數的節點正常,集群就能正常提供服務,只有在 ZK節點掛得太多,只剩一半或不到一半節點能作業,集群才失效,
所以:
-
3 個節點的 cluster 可以掛掉 1 個節點(leader 可以得到 2 票>1.5)
-
2 個節點的 cluster 就不能掛掉任何 1 個節點了(leader 可以得到 1 票<=1)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/542576.html
標籤:其他
下一篇:聊聊GC是如何快速列舉根節點的

