在學習的過程中,我們總需要一個來自靈魂的拷問: 爲什麼?
爲什麼會產生Zookeeper
這個問題有深度,那要從五百萬年說起,在遙遠的塞伯坦星球.....
扯遠了...
在遙遠在單機單服務的時代 , 想要擴展服務 , 只能增加硬件配置 . 現在看來 ,有以下問題:
- 硬件貴 (有錢的老闆也能接受)
- 擴展麻煩 (在還沒有實時擴展的雲服務時,加硬件就意味着宕機)
- 沒有容錯 (一旦生產異常,服務就掛了,災難)
這時候,分佈式應運而生,將業務拆分開來,比如:倉庫,訂單,支付等等,各管各的 , 風險拆分, 比如: 訂單服務掛了,不影響倉庫和支付.
這是分佈式的初始模式, 風險少了, 再用個Nginx做個代理,集羣化.然後似乎大概也許Mybe可以 浪裏個浪了 ~~
當項目越來越大,模塊越來越多.又來問題了.
一開始的服務拆分並不一定很理想, 再加後期業務迭代, 可能產生很多個模塊,各模塊間的調用混亂 , 一條業務線中不知道串了多少個模塊.
下圖參考下: T_T
當你想了解一條線的時候,心裏可不止一萬個那啥...
那麼急需,迫切的需要一個可以把這個東西治理一下的工具.
buling~ buling ~ zookeeper來啦
zookeeper解決了哪些問題
先來感受下使用zookeeper後的趕腳
啊.kimoji...
概念
Zookeeper是一個高性能的分佈式系統的協調服務
Zookeeper特性
-
最終一致性
保證各個節點服務器數據能夠最終達成一致,zk的招牌功能
-
順序性
從同一客戶端發起的事務請求,都會最終被嚴格的按照其發送順序被應用到zk中,這也是zk選舉leader的依據之一
-
可靠性
凡是服務器成功的使用一個事務,並完成了客戶端的響應,那麼這個事務所引起的服務端狀態變更會被一直保留下去
-
實時性
zk不能保證多個客戶端能同時得到剛更新的數據,所以如果要最新數據,需要在讀數據之前強制調用sync接口來保證數據的實時性
-
原子性
數據更新要麼成功要麼失敗
-
單一視圖
無論客戶端連的是哪個節點,看到的數據模型對外一致
Zookeeper中的四種角色
-
Leader
更新系統狀態,處理事務請求,負責進行投票的發起和決議
-
Leaner
- Follower
處理客戶端非事務請求,並向客戶端返回結果. 將寫事務請求轉發給Leader,同步Leadker的狀態. 選舉過程中參與投票.可被選舉.
- Observer
接收客戶端讀請求,將客戶端寫請求轉發給Leader,不參與投票過程,只同步Leader狀態.目的是爲了擴展系統,提高讀取速度.
-
Client
請求發起方
Zookeeper的寫入流程
數據寫入最終一致性ZAB算法 .
Leader負責處理寫事務請求,Follower負責向Leader轉發寫請求,響應Leader提出的提議.
Zookeeper選舉機制
先了解幾個關鍵字:
狀態
- looking : 尋找Leader狀態,處於該狀態需要進入選舉過程.或正在進行選舉.
- Leading : Leader的狀態,表示當前服務的角色爲Leader
- Following : 從節點 , Leader已經選出,當前爲從節點
- Observer : 觀察者狀態
事務ID
- zxid : 64位數字,Leader分配,全局唯一且遞增.值越大,表示操作越新.
流程
- 每個節點發出一個投票,內容是(myid,zxid)
- 接收來自各個節點的投票,
- 進行投票處理和統計
- zxid對比,選取較大的
- zxid一樣的,選取myid較大的
- 當有一半以上的服務器選出同一個節點.選舉結束.
- 被選舉的Leader節點更新狀態
Zookeeper的數據模型:znode
znode是zk特有的數據模型,是zk中數據最小單元,znode上能保存數據,通過掛載子節點形成一個樹狀的層次結構。根由/斜槓開始。
節點類型
- 持久節點
- 臨時節點
- 順序節點
- 不同節點類型的組合。
Zookeeper版本
- 當前數據節點的版本號
- 當前數據子節點版本號
- acl權限變更版本號
主要用來通過版本號來實現分佈式鎖的一些控制
Zookeeper : znode watch機制
znode watch機制也是zk的核心功能之一,是配置管理功能的基石。client端通過註冊watch對象後,只要相應的znode觸發更改,watch管理器就會向客戶端發起回調,可藉此機制實現配置管理的分佈式更新和同步隊列等場景。
參考
[1]洛神獨舞:Zookeeper架構原理和使用場景總結