1、什麼是Zookeeper
ZooKeeper是一個爲分佈式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分佈式同步、組服務等。node
它的核心是:文件系統 + 通知機制算法
2、重要特色
- 一個領導者(Leader),多個跟隨者(Follower)組成的集羣
- 集羣中只要有半數以上節點存活,Zookeeper集羣就能正常服務
- 全局數據一致性,每一個server保存一份相同的副本,client不管連接哪一個server,獲得的數據都是一致的
- 更新請求順序執行,來自同一個client的請求按順序執行
- 數據更新原子性,一次數據更新要麼成功要麼失敗
- 實時性,在必定時間範圍內,client能讀到最新數據
3、數據結構
Zookeeper數據模型的結構與Unix文件系統很相似,總體上可看做是一棵樹,每一個節點稱做一個ZNode。每一個ZNode默認能存儲1MB數據,每一個ZNode均可以經過其路徑惟一標識。bash
4、應用場景(※)
- 分佈式鎖
- 服務註冊和發現
- 利用Znode和Watcher,能夠實現分佈式服務的註冊和發現。最著名的應用就是阿里的分佈式RPC框架Dubbo。
- 共享配置和狀態信息
- Redis的分佈式解決方案Codis(豌豆莢),就利用了Zookeeper來存放數據路由表和 codis-proxy 節點的元信息。同時 codis-config 發起的命令都會經過 ZooKeeper 同步到各個存活的 codis-proxy。
5、選舉機制(※)
5.1 半數機制(paxos協議)
集羣中半數以上機器存活,集羣可用,因此Zookeeper適合安裝奇數臺服務器服務器
5.2 內部選舉
在分佈式系統中選主最直接的方法是直接選定集羣的一個節點爲leader,其它的節點爲follower,這樣引入的一個問題是若是leader節點掛掉,整個集羣就掛掉了。須要有一種算法自動選主,若是leader節點掛掉,則從follower節點中選出一個主節點。網絡
1. 選舉階段 Leader electionsession
最大ZXID也就是節點本地的最新事務編號,包含epoch和計數兩部分。epoch是紀元的意思,至關於Raft算法選主時候的term,標識當前leader週期,每次選舉一個新的Leader服務器後,會生成一個新的epoch數據結構
- 全部節點處於Looking狀態,各自依次發起投票,投票包含本身的服務器ID和最新事務ID(ZXID)。
- 若是發現別人的ZXID比本身大,也就是數據比本身新,那麼就從新發起投票,投票給目前已知最大的ZXID所屬節點。
- 每次投票後,服務器都會統計投票數量,判斷是否有某個節點獲得半數以上的投票。若是存在這樣的節點,該節點將會成爲準Leader,狀態變爲Leading。其餘節點的狀態變爲Following。
2. 發現階段 Discovery框架
- 爲了防止某些意外狀況,好比因網絡緣由在上一階段產生多個Leader的狀況。
- Leader集思廣益,接收全部Follower發來各自的最新epoch值。Leader從中選出最大的epoch,基於此值加1,生成新的epoch分發給各個Follower。
- 各個Follower收到全新的epoch後,返回ACK給Leader,帶上各自最大的ZXID和歷史事務日誌。Leader選出最大的ZXID,並更新自身歷史日誌。
3. 同步階段 Synchronization分佈式
Leader剛纔收集獲得的最新歷史事務日誌,同步給集羣中全部的Follower。只有當半數Follower同步成功,這個準Leader才能成爲正式的Leader。ui
6、ZNode 內構
6.1 節點類型
持久persistent:client 和 server 斷開鏈接後,建立的節點不刪除
短暫ephemeral:client 和 server 斷開鏈接後,建立的節點本身刪除
另外分 有序和無序。建立有序節點時,會自動將節點名增長序列號
$ create -s /test/no1 "no1"
Created /test/no10000000000
複製代碼
6.2 內部結構
- data: ZNode存儲的數據信息,每一個節點數據最大不超過1MB
- ACL(Access Control List): 記錄訪問權限,哪些人或哪些IP可訪問本節點
- child: 當前節點的子節點
- stat: 各類元數據,好比事務ID、版本號、時間戳、大小等
- czxid- 引發這個 znode 建立的 zxid,建立節點的事務的 zxid
- ctime - znode 被建立的毫秒數
- mzxid - znode 最後更新的 zxid
- mtime - znode 最後修改的毫秒數
- pZxid-znode 最後更新的子節點 zxid
- cversion - znode 子節點變化號,znode 子節點修改次數 7)dataversion - znode 數據變化號
- aclVersion - znode 訪問控制列表的變化號
- ephemeralOwner- 若是是臨時節點,這個是znode擁有者的 session id。若是不是臨時節點則是 0
- dataLength- znode 的數據長度
- numChildren - znode 子節點數量
7、監聽器原理(※)
客戶端 |
服務端 |
Main進程 |
|
建立ZK客戶端,會建立connet網絡鏈接通訊線程,listener監聽線程 |
|
經過connect線程將註冊的監聽事件發送給Zookeeper服務端 |
|
|
將監聽事件添加到註冊監聽器列表 |
|
監聽到有數據或路徑變化,將消息發送給listener |
listener線程內部調用process方法 |
|
8、常見監聽
- 子節點增減變化(以下示例)
- 節點數據變化
9、寫數據流程
- 客戶端發出寫入數據請求給任意Follower。
- Follower把寫入數據請求轉發給Leader。
- Leader採用二階段提交方式,先發送Propose廣播給Follower。
- Follower接到Propose消息,寫入日誌成功後,返回ACK消息給Leader。
- Leader接到半數以上ACK消息,返回成功給客戶端,而且廣播Commit請求給Follower
10、命令
客戶端鏈接
zkcli -server host:port
create [-s] [-e] path data acl
$ create /test "data"
Created /test
複製代碼
get path [watch] watch指是否監聽
[zk: 10.96.86.22:2181(CONNECTED) 10] get /test
data
cZxid = 0x10
ctime = Mon Feb 25 16:34:23 CST 2019
mZxid = 0x10
mtime = Mon Feb 25 16:34:23 CST 2019
pZxid = 0x10
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
複製代碼
參考
《從Paxos到ZooKeeper》經典
1、zookeeper 基礎介紹
2、zookeeper 集羣搭建
3、zookeeper 應用實現-配置中心