Zookeeper
前言
前段時間,被問到過Zookeeper的相關問題,蛋撻一籌莫展,所以在工作之餘整理了Zookeeper的一些基本知識已作知識儲備的提升。下面是個人在學習Zookeeper過程中整理的思維導圖,此篇基礎也是圍繞這個思維導圖展開的。許多概念性整理大多來自書籍和網絡,在這裏感謝許多大神博主的分享。
什麼是Zookeeper
官宣概念:Zookeeper是一個高性能,分佈式的,開源分佈式應用協調服務。它提供了簡單原始的功能,分佈式應用可以基於它實現更高級的服務(如Dubbo基於Zookeeper),比如,配置管理,集羣管理,命名空間。它被設計爲易於編程,使用文件系統目錄樹作爲數據模型。服在端跑在java上,提供java和C的客戶端API。
我個人通常會通俗的理解成節點管理器。
Zookeeper的特點
-
最終一致性:client不論連接到哪個Server,展示給它都是同一個視圖。
-
可靠性:具有簡單、健壯、良好的性能,如果消息m被到一臺服務器接受,那麼它將被所有的服務器接受。
-
實時性:Zookeeper保證客戶端將在一個時間間隔範圍內獲得服務器的更新信息,或者服務器失效的信息。但由於網絡延時等原因,Zookeeper不能保證兩個客戶端能同時得到剛更新的數據,如果需要最新數據,應該在讀數據之前調用sync()接口。
-
等待無關:慢的或者失效的client不得干預快速的client的請求,使得每個 client都能有效的等待。
-
原子性:更新只有成功或者失敗,沒有中間狀態。
-
順序性:包括全局有序和偏序兩種:全局有序是指如果在一臺服務器上消息a在消息b前發佈,則在所有Server上消息a都將在消息b前被髮布;偏序是指如果一個消息b在消息a後被同一個發送者發佈,a必將排在b前面。
Zookeeper的作用
命名服務
在分佈式系統中,通過使用命名服務,客戶端應用能夠根據指定名字來獲取資源或服務的地址,提供者等信息。被命名的實體通常可以是集羣中的機器,提供的服務地址,遠程對象等等——這些我們都可以統稱他們爲名字(Name)。其中較爲常見的就是一些分佈式服務框架中的服務地址列表。通過調用ZK提供的創建節點的API,能夠很容易創建一個全局唯一的path,這個path就可以作爲一個名稱。
配置管理
程序總是需要配置的,如果程序分散部署在多臺機器上,要逐個改變配置就變得困難。現在把這些配置全部放到Zookeeper上去,保存在 Zookeeper的某個目錄節點中,然後所有相關應用程序對這個目錄節點進行監聽,一旦配置信息發生變化,每個應用程序就會收到Zookeeper 的通知,然後從 Zookeeper獲取新的配置信息應用到系統中就可以了。
集羣管理
所謂集羣管理無在乎兩點:是否有機器退出和加入以及選舉master。 對於第一點,所有機器約定在父目錄GroupMembers下創建臨時目錄節點,然後監聽父目錄節點的子節點變化消息。一旦有機器掛掉,該機器與 zookeeper的連接斷開,其所創建的臨時目錄節點被刪除,所有其他機器都收到通知。
分佈式鎖
有了zookeeper的一致性文件系統,鎖的問題變得容易。鎖服務可以分爲兩類,一個是保持獨佔,另一個是控制時序。 對於第一類,我們將zookeeper上的一個znode看作是一把鎖,通過createznode的方式來實現。所有客戶端都去創建 /distribute_lock 節點,最終成功創建的那個客戶端也即擁有了這把鎖。用完刪除掉自己創建的distribute_lock 節點就釋放出鎖。 對於第二類, /distribute_lock 已經預先存在,所有客戶端在它下面創建臨時順序編號目錄節點,編號最小的獲得鎖,用完刪除,依次方便。
隊列管理
兩種類型的隊列: 1、同步隊列,當一個隊列的成員都聚齊時,這個隊列纔可用,否則一直等待所有成員到達。 2、隊列按照 FIFO方式進行入隊和出隊操作。 第一類,在約定目錄下創建臨時目錄節點,監聽節點數目是否是我們要求的數目。 第二類,和分佈式鎖服務中的控制時序場景基本原理一致,入列有編號,出列按編號。
Zookeeper的基本角色
leader
事務請求的唯一調度者和處理者,保證集羣中事務處理順序,集羣內部各服務器的調度者
Follower
處理客戶端非事務請求,轉發事務請求給leader服務器。參與事務請求proposal的投票,參與leader選舉投票。
Observer(可伸縮性)
充當一個觀察者的角色,和Follower類似,對非事務請求,都可以進行獨立處理。而對於事務請求,則交給leader來處理。和follower的區別是,Observer不參與任何形式的投票。通常用於不影響集羣事務處理能力的情況下增加集羣非事務處理能力。
Zookeeper的基本結構
Zookeeper採用樹形層次結構,樹中的每個節點被稱爲—Znode。 Znode,兼具文件和目錄兩種特點:
-
像文件一樣維護着數據、元信息、ACL、時間戳等數據結構
-
像目錄一樣可以作爲路徑標識的一部分。 每個Znode由3部分組成: ① stat:此爲狀態信息, 描述該Znode的版本, 權限等信息 ② data:與該Znode關聯的數據 ③ children:該Znode下的子節點
cZxid = 0x100000009 節點創建時的zxid.
ctime = Mon Sep 18 10:55:36 CST 2017 節點創建時的時間
mZxid = 0x100000009 節點最新一次更新發生時的zxid
mtime = Mon Sep 18 10:55:36 CST 2017 節點最新一次更新發生時的時間
pZxid = 0x100000009子節點最新一次更新發生時的時間戳
cversion = 0 其子節點的更新次數
dataVersion = 0 節點數據的更新次數
aclVersion = 0 節點ACL(授權信息)的更新次數.
ephemeralOwner = 0x0 ephemeralOwner值表示與該節點綁定的session id
dataLength = 7 節點數據的字節數
numChildren = 0 子節點個數
節點類型
1、PERSISTENT-持久化目錄節點 客戶端與zookeeper斷開連接後,該節點依舊存在 2、PERSISTENT_SEQUENTIAL-持久化順序編號目錄節點 客戶端與zookeeper斷開連接後,該節點依舊存在,只是Zookeeper給該節點名稱進行順序編號 3、EPHEMERAL-臨時目錄節點 客戶端與zookeeper斷開連接後,該節點被刪除 4、EPHEMERAL_SEQUENTIAL-臨時順序編號目錄節點 客戶端與zookeeper斷開連接後,該節點被刪除,只是Zookeeper給該節點名稱進行順序編號 臨時節點不允許有子節點
Zookeeper的原理
ZAB協議
ZAB 協議包括兩種基本的模式,分別是崩潰恢復和消息廣播。
崩潰恢復
當整個服務框架在啓動過程中,或是當 Leader 服務器出現網絡中斷、崩潰退出與重啓等異常情況時, ZAB 協議就會進入恢復模式並選舉產生新的 Leader 服務器。當選舉產生了新的Leader 服務器同時集羣中已經有過半的機器與該 Leader 服務器完成了狀態同步之後,ZAB 協議就會退出恢復模式。
消息廣播
當集羣中已經有過半的 Follower 服務器完成了和 Leader 服務器的狀態同步,那麼整個服務框架就可以進入消息廣播模式了。當一臺同樣遵守 ZAB 協議的服務器啓動後加入到集羣中時,如果此時集羣中已經存在一個 Leader 服務器在負責進行消息廣播 , 那麼新加人的服務器就會自覺地進人數據恢復模式:找到 Leader 所在的服務器,並與其進行數據同步,然後一起參與到消息廣播流程中去。
Leader選舉
當leader崩潰或者leader失去大多數的follower,這時候zk進入恢復模式,恢復模式需要重新選舉出一個新的leader,讓所有的server都恢復到一個正確的狀態。
-
客戶端發送寫請求給Follower
-
Followe把請求轉發給Leader
-
Leader接受到請求之後發起投票
-
Leader彙總投票結果,同意則寫入,然後由Follower返回結果給Client,否則不寫入,也是通過這種方式實現 了原子事務性
所以ZK的節點一般推薦爲奇數個: 當多數Server寫成功,則任務數據寫成功如果有3個Server,則兩個寫成功即可;如果有4或5個Server,則三個寫成功即可。Server數目一般爲奇數(3、5、7)如果有3個Server,則最多允許1個Server掛掉;如果有4個Server,則同樣最多允許1個Server掛掉由此,可以節省服務器資源。
總結
Zookeeper作爲一個節點管理系統,在日常的工作應用中也是比較多的,此前ZK的運維開發我不曾涉及,也就荒廢了學習,在最近的一些事情中也是發現,知識儲備的提高只有好處沒有壞處,在後續的工作學習當中,蛋撻也會不停自勉,更加深入全面的學習知識。
作者:蛋撻
日期:2019.02.18
多少事,從來急;天地轉,光陰迫;一萬年太久,只爭朝夕!