zookeeper集羣知識點
文章目錄
什麼是zookeeper
ZooKeeper 是一個開源的分佈式協調服務,基於google的chubby,ZooKeeper框架最初是在“Yahoo!"上構建的,用於以簡單而穩健的方式訪問他們的應用程序。 後來,Apache ZooKeeper成爲Hadoop,HBase和其他分佈式框架使用的有組織服務的標準。 例如,Apache HBase使用ZooKeeper跟蹤分佈式數據的狀態。ZooKeeper 的設計目標是將那些複雜且容易出錯的分佈式一致性服務封裝起來,構成一個高效可靠的原語集,並以一系列簡單易用的接口提供給用戶使用。它也是一個典型的分佈式數據一致性解決方案.
缺點:
難以做到水平拓展(也就是動態加機器),它只能改配置以後全部重啓或者按個重啓
zookeeper的特性
特性 | 介紹 |
---|---|
順序一致性 | 數據一致性,數據按照順序分批入庫 |
原子性 | 要麼同時成功,要麼同時失敗,過半投票機制 |
單一視圖 | 不管客戶端連接到哪個服務器,所看到的數據都是一樣的 |
可靠性 | 一單服務器端處理完一個事務請求,並且客戶端獲得了服務端的返回成功標誌,那這個事務造成的變化會一直保存在服務器上 |
最終一致性(實時性) | 一個事務被成功提交成功以後,那麼所有客戶端從服務端讀取的數據基本是一致的,是一個無限接近實時的. |
zookeeper主要提供了文件系統和通知機制,這兩個也是它的核心.
zookeeper的數據模型
可以理解爲文件系統,也就是樹形結構,類似於操作系統的文件管理器,每一個節點稱爲:znode (是zookeeper中的最小數據單元,貌似最大是1M)。每一個znode上都可以保存數據和掛載子節點
四種節點以及特性:
節點類型 | 特性 |
---|---|
持久化節點(PERSISTENT) | 節點創建後會一直存在zookeeper服務器上,直到主動刪除 |
持久化有序節點(PERSISTENT_SEQUENTIAL) | 每個節點都會爲它的一級子節點維護一個順序 |
臨時節點(EPHEMERAL) | 臨時節點的生命週期和客戶端的會話保持一致。當客戶端會話失效,該節點自動清理 |
臨時有序節點(EPHEMERAL_SEQUENTIAL) | 在臨時節點上多勒一個順序性特性 |
zookeeper的常見應用場景
場景 | 依據 |
---|---|
發佈訂閱 | wacther機制和znode |
分佈式鎖 | 臨時有序節點和wacther機制 |
分佈式隊列 | 臨時有序節點 |
負載均衡 | 負載均衡算法和znode |
ID生成器 | 臨時有序節點 |
統一命名服務 | znode |
master選舉 | znodes |
等等 | … |
zookeeper集羣角色
zookeeper一般都是由2n+1臺服務器構成的,而這個2n+1不包含obsever節點,而集羣爲奇數主要是根據存活量以及吞吐量去考慮的.集羣主要由三種角色構成如下表:
角色 | 職責 | 責任 |
---|---|---|
leader | 領導者 | leader是zookeeper集羣的核心節點, 1.它是事務請求的唯一調度和處理者,它要保證集羣事務處理的順序性; 2.它是集羣內部各個服務器的調度者 |
follower | 跟隨者 | 1.它主要處理客戶端非事務請求,以及轉發事務請求給leader,事務請求就是會讓數據產生變化的請求; 2.參與事務請求提議的投票(客戶端的一個事務請求,需要半數服務器投票通過以後才能通知leader去commit,leader會發起一個提案,要求follower去投票); 3.參與leader選舉的投票,與2的投票不是一回事. |
observer | 觀察者 | 觀察zookeeper集羣中的最新狀態的變化並且將這些狀態同步到observer服務器上,不參與投票,增加observer不會影響集羣的事務處理能力,反而可以提升集羣的非事務處理能力,也就是常說的讀吞吐量. |
zookeeper的Watcher機制
zookeeper提供了分佈式數據發佈/訂閱,zookeeper允許客戶端向服務器註冊一個watcher監聽。當服務器端的節點觸發指定事件的時候會觸發watcher。服務端會向客戶端發送一個事件通知
watcher的通知是一次性,一旦觸發一次通知後,該watcher就失效
Watcher對應Event.EventType中的狀態,Watcher的監聽的事件類型如下:
type | 含義 |
---|---|
None(-1) | 空,也就是剛建立連接那會 |
NodeCreated(1) | 創建子節點觸發 |
NodeDeleted(2) | 刪除子節點觸發 |
NodeDataChanged(3) | 修改觸發 |
NodeChildrenChanged(4) | 更新子節點觸發 |
連接狀態對應Event.KeeperState中的狀態:
狀態 | 含義 |
---|---|
Expired | 在一定時間內客戶端沒有收到服務器的通知, 則認爲當前的會話已經過期了。 |
Disconnected | 斷開連接的狀態 |
SyncConnected | 客戶端和服務器端在某一個節點上建立連接,並且完成一次version、zxid同步 |
authFailed | 授權失敗 |
zookeeper的會話
在 ZooKeeper 中,一個客戶端連接是指客戶端和服務器之間的一個 TCP 長連接。客戶端啓動的時候,首先會與服務器建立一個 TCP 連接,從第一次連接建立開始,客戶端會話的生命週期也開始了。通過這個連接,客戶端能夠通過心跳檢測與服務器保持有效的會話,也能夠向Zookeeper服務器發送請求並接受響應,同時還能夠通過該連接接收來自服務器的Watch事件通知。 Session的sessionTimeout值用來設置一個客戶端會話的超時時間。當由於服務器壓力太大、網絡故障或是客戶端主動斷開連接等各種原因導致客戶端連接斷開時,只要在sessionTimeout規定的時間內能夠重新連接上集羣中任意一臺服務器,那麼之前創建的會話仍然有效.
會話狀態如下:
狀態 | 含義 |
---|---|
NOT_CONNECTED | 未連接 |
CONNECTING | 連接中 |
CONNECTED | 已連接 |
CLOSED | 關閉 |
注意點:
連接中和已連接之間是可以相互轉換的
分桶策略:將類似的會話放在同一區塊中進行管理,以便於Zookeeper對會話進行不同區塊的隔離處理以及同一區塊的統一處理。
分配原則:每個會話的“下次超時時間點”(ExpirationTime)
計算公式:
ExpirationTime = currentTime + sessionTimeout ExpirationTime
= (ExpirationTime_ / ExpirationInrerval + 1) * ExpirationInterval
ExpirationInterval 是指 Zookeeper 會話超時檢查時間間隔,默認 tickTime
zookeeper的Server工作狀態
服務器具有四種狀態,分別是LOOKING、FOLLOWING、LEADING、OBSERVING。
狀態 | 含義 |
---|---|
LOOKING | 尋找Leader狀態。當服務器處於該狀態時,它會認爲當前集羣中沒有Leader,因此需要進入Leader選舉狀態。 |
FOLLOWING | 跟隨者狀態。表明當前服務器角色是Follower。 |
LEADING | 領導者狀態。表明當前服務器角色是Leader。 |
OBSERVING | 觀察者狀態。表明當前服務器角色是Observer。 |
zookeeper的ACL權限
zookeeper提供控制節點訪問權限的功能,用於有效的保證zookeeper中數據的安全性。避免誤操作而導致系統出現重大事故.
ACL | 含義 |
---|---|
CREATE | 創建子節點的權限 (針對子節點的權限控制) |
READ | 獲取節點數據和子節點列表的權限 |
WRITE | 更新節點數據的權限 |
DELETE | 刪除子節點的權限 (針對子節點的權限控制) |
ADMIN | 設置節點ACL的權限 |
關於Scheme,標準格式是 [類型:數據:權限字符串]
權限scheme(類型) | 含義和用法 |
---|---|
ip | 指定的IP地址,類似白名單,ip:ip地址或號段:權限字符串crwda,就是上邊的權限首字母小寫 |
digest | 用戶名和加密密碼的格式,digest:用戶名:加密的密碼:權限字符串crwda |
auth | 用戶名和明文密碼格式,auth:用戶名:密碼:crwda |
world | 所有人都可以,world:anyone:權限字符串crwda |
super | 超級管理員權限 |
關於API(ZooDefs.Ids)的權限含義
ZooDefs.Ids | 含義 |
---|---|
OPEN_ACL_UNSAFE | 完全開放的ACL,任何連接的客戶端都可以操作該屬性znode |
CREATOR_ALL_ACL | 只有創建者纔有ACL權限 |
READ_ACL_UNSAFE | 只能讀取ACL |
ANYONE_ID_UNSAFE | ID代表任何人 |
AUTH_IDS | 可以設置ACL,代替了已經認證過客戶端的IDs |
zookeeper的常用命令
命令 | 含義 |
---|---|
stat path [watch] | 查看node狀態, stat 節點名 註冊watcher |
set path data [version] | 更新數據,set 節點名 數據 版本號,默認-1,可以理解爲樂觀鎖 |
ls path [watch] | 查看節點的子節點,沒有stat信息, ls 節點名 註冊watcher |
ls2 path [watch] | 查看節點的子節點和tat信息, ls2 節點名 註冊watcher |
setAcl path acl | 設置節點權限 |
delete path [version] | 刪除子節點,delete 節點名 版本號 |
get path [watch] | 獲取節點內容和stat信息,get 節點名 註冊watcher |
create [-s] [-e] path data acl | 以兩種格式創建子節點,-e是臨時節點,-s是有序節點,create -s/-e 節點名 數據 權限 |
getAcl path | 獲取節點權限 |
… | … |
stat信息含義:
屬性 | 含義 |
---|---|
cversion | 子節點的版本號 |
aclVersion | 表示acl的版本號,修改節點權限 |
dataVersion | 表示的是當前節點數據的版本號 |
czxid | 節點被創建時的事務ID |
mzxid | 節點最後一次被更新的事務ID |
pzxid | 當前節點下的子節點最後一次被修改時的事務ID |
ctime | 創建時間 |
mtime | 更新時間 |
ephemeralOwner | 創建臨時節點的時候,會有一個sessionId 。 該值存儲的就是這個sessionid |
dataLength | 數據值長度 |
numChildren | 子節點數 |
zookeeper集羣的leader選舉
zookeeper集羣的leader選舉與它可以實現的master選舉是不一樣的,leader選舉是一個更爲複雜的過程,而zookeeper提供了三種算法來實現集羣的leader選舉,主要有:leaderElection、authFasetLeaderElection、FastLeaderElection.集羣默認採用的是FastLeaderElection算法,驗證算法可以去查看一下zookeeper的源碼,在源碼的QUorumPeer.java中有一個同步的startLeaderElection方法,這個也是leader選舉的入口,也算是看源碼的入口之一.源碼是用ant編譯的,這裏不過多說了.在這個startLeaderElection方法最後有一個createElectionAlgorithm(int electionAlgorithm)方法,點進去之後就可以看到對應的選舉算法了.這裏主要還是關注FastLeaderElection算法:
在FastLeaderElection算法中有幾個主要的參數:
參數 | 作用 |
---|---|
serverid | 在配置集羣的時候給定的服務器id,也就是myid文件中的數字 |
zxid | 服務器在運行時產生的數據id,而zxid越大表示數據越新,所以選舉的時候它起到了很重要的作用 |
Epoch | 選舉的輪數,表示的就是當前是進入到選舉那一輪了,然後每次選舉一輪他就自增1,是一個原子操作 |
ServerState | Looking、Following、Observering、Leadeing這四種狀態 |
主要的選舉過程可以看我的另一篇博文zookeeper的leader選舉過程
選舉大致流程如下,如有錯誤歡迎指正:
ZAB協議
ZAB(ZooKeeper Atomic Broadcast 原子廣播) 協議是爲分佈式協調服務 ZooKeeper 專門設計的一種支持崩潰恢復的原子廣播協議。 在 ZooKeeper 中,主要依賴 ZAB 協議來實現分佈式數據一致性,基於該協議,ZooKeeper 實現了一種主備模式的系統架構來保持集羣中各個副本之間的數據一致性。
ZAB 協議主要分爲兩種基本的模式:崩潰恢復模式和消息廣播模式
當zookeeper集羣剛剛啓動或者 Leader 服務器出現網絡中斷、崩潰退出與重啓等異常情況時,ZAB 協議就會進入恢復模式並選舉產生新的Leader服務器,同時集羣中已經有過半的機器與該Leader服務器完成了狀態同步(數據同步)之後,ZAB協議就會退出恢復模式,當集羣中有過半的Follower服務器完成了和Leader服務器的狀態同步,那麼整個服務框架就會進入消息廣播模式,而當進行拓展機器時,新加入的follower服務器在啓動後就會自覺進入恢復模式,當然前提是leader還存活着,不然會去競爭leader,當接收到leader的廣播之後會和leader建立連接進行數據同步,然後再一起進入消息廣播正式工作.
在集羣啓動過程中會經歷如下的狀態
狀態 | 含義 |
---|---|
LeaderElection(選舉階段) | 節點在一開始都處於選舉階段,只要有一個節點得到超半數節點的票數,它就可以當選準 leader。 |
Discovery(發現階段) | 在這個階段,followers 跟準 leader 進行通信,同步 followers 最近接收的事務提議。 |
Synchronization(同步階段) | 同步階段主要是利用 leader 前一階段獲得的最新提議歷史,同步集羣中所有的副本。同步完成之後 準 leader 纔會成爲真正的 leader。 |
Broadcast(廣播階段) | 到了這個階段,Zookeeper 集羣才能正式對外提供事務服務,並且 leader 可以進行消息廣播。同時如果有新的節點加入,還需要對新節點進行同步。 |
原理
- 在zookeeper 的主備模式下,通過zab協議來保證集羣中各個副本數據的一致性
- zookeeper使用的是單一的主進程來接收並處理所有的事務請求,並採用zab協議,把數據的狀態變更以事務請求的形式廣播到其他的節點
- zab協議在主備模型架構中,保證了同一時刻只能有一個主進程來廣播服務器的狀態變更
- 所有的事務請求必須由全局唯一的服務器來協調處理,這個的服務器叫leader,其他的叫follower,leader節點主要負責把客戶端的事務請求轉化成一個事務提議(proposal),並分發給集羣中的所有follower節點,再等待所有follower節點的反饋(ack)。一旦超過半數服務器進行了正確的反饋,那麼leader就會commit這條消息.
- (1)zab協議一定要保證已經被leader提交的事務也能夠被所有follower提交;(2)而且需要保證在崩潰恢復過程中跳過哪些已經被丟棄的事務.
第5點的場景:
- 一個事務請求被leader處理並且廣播給所有follower以後,follower節點也反饋會了ack給leader,並且leader也commit了,但是在leader把自己已經commit的消息廣播出去之前,leader掛了.則事務可以被follower提交
- 一個事務請求被leader處理了,但是在廣播給所有follower節點之前掛了,則事務要丟棄