?什么是ZooKeeper虱朵?ZooKeeper是一個分布式布持、開源的分布式應用協(xié)作服務豌拙。它提供了一組簡單的原語,分布式應用程序可以在這些原語的基礎上實現更高級別的服務题暖,用于同步按傅、配置維護、組命名,提供簡單易用的接口給用戶使用胧卤。
?本文將介紹ZooKeeper的基本概念唯绍、使用場景、ZAB協(xié)議和請求處理枝誊。
ZooKeeper的概念和基礎
1. 服務架構
?ZooKeeper本身是一個高可用的服務况芒,ZooKeeper集群中服務器有三種角色leader、follower叶撒、observer绝骚,leader提供讀和寫的服務耐版,follower只提供讀的服務和參與leader選舉,observer和follower的區(qū)別是observer不參與選舉压汪。
2. 數據結構
?ZooKeeper的數據結構類似于一個文件系統(tǒng)粪牲。存放一個個的數據節(jié)點(Znode),Znode的屬性有永久(persistent)止剖、臨時(ephemeral)和有序(sequential)腺阳。
- 永久:創(chuàng)建成功之后將永久存在,只能通過調用delete來進行刪除滴须。
- 臨時:當創(chuàng)建該節(jié)點的客戶端崩潰或關閉了與ZooKeeper的連接時舌狗,這個節(jié)點就會被刪除。
- 有序:按照創(chuàng)建的時間順序節(jié)點會分配唯一個單調遞增的整數扔水。
總之痛侍,znode一共有4種類型:永久的(persistent)、臨時的(ephemeral)魔市、永久有序的(persistent_sequential)和臨時有序的(ephemeral_sequential)主届。
3. 監(jiān)控與通知
?Watcher是Zookeeper中很重要的機制〈拢客戶端通過對znode創(chuàng)建watcher當節(jié)點發(fā)生變化的時候(節(jié)點刪除君丁、數據更改、子節(jié)點變化等)将宪,ZooKeeper將會通知注冊Watcher的客戶端節(jié)點已經變更绘闷。
?監(jiān)聽事件有推和拉的形式,所謂推就是事件觸發(fā)之后服務器向客戶端推送數據较坛,而拉就是客戶端輪詢服務器檢查事件是否觸發(fā)印蔗。而ZooKeeper采用推和拉結合的形式,事件觸發(fā)之后丑勤,服務器給客戶端推送事件(不包含事件的內容华嘹,只有發(fā)生了什么事件),客戶端收到通知之后去服務器拉去最新的數據法竞,采用這種方式每次每次通知只需要傳輸少量數據就行了耙厚,減少I/O壓力。需要注意的是ZooKeeper在事件通知之后會將Watcher給刪除岔霸,為了繼續(xù)監(jiān)聽薛躬,客戶端必須在每次通知后設置一個新的Watcher。
4. 會話(Session)
?在對ZooKeeper集合執(zhí)行任何請求前呆细,一個客戶端必須先與服務建立會話泛豪∈薨#客戶端與服務器將會建立一個TCP的長連接放妈,第一次建立連接的時候也是Session開始的時候册赛,客戶端與服務器通過這個連接發(fā)送心跳監(jiān)控彼此存活的狀態(tài)笆豁。客戶端可以設置會話超時時間sessionTimeout价卤,在集群模式下劝萤,客戶端和ZooKeeper服務器斷開連接之后,只要間隔時間不超過sessionTimeout之前建立的會話依然有效慎璧。
5. 應用
?因為ZooKeeper自身的分布式一致性和特殊的數據結構床嫌,可以使用ZooKeeper解決很多分布式系統(tǒng)的問題,比如數據的發(fā)布訂閱胸私、分布式鎖厌处、Master選舉、分布式協(xié)調等功能岁疼。
- 分布式鎖
使用ZooKeeper的臨時有序節(jié)點這個特性阔涉,實現分布式鎖。比如命名一個臨時節(jié)點/lock捷绒,客戶端都去爭奪創(chuàng)建這個節(jié)點瑰排,創(chuàng)建成功就代表獲取鎖成功,由于只會有一個路徑相同的節(jié)點存在暖侨,其他客戶端不會再創(chuàng)建這個節(jié)點成功椭住。創(chuàng)建失敗則注冊Watcher檢測/lock節(jié)點的變化。當獲取鎖成功的客戶端執(zhí)行完自身邏輯之后去釋放鎖就是刪除/lock節(jié)點字逗,或者客戶端崩潰由于是臨時節(jié)點也會將鎖釋放京郑。其他客戶端監(jiān)聽到節(jié)點變化事件之后,再次去爭奪鎖葫掉。 -
實現主從模式
主從模式可以使用上圖的數據結構可以實現一個主從模式的服務集群傻挂,master的選舉、任務的分配挖息。/master使用一個臨時節(jié)點,所有集群中的服務器都去爭奪創(chuàng)建它兽肤,但是只要一個服務器會創(chuàng)建成功他就是master節(jié)點套腹,其他服務器就分配到/workers作為從節(jié)點,并監(jiān)聽/master節(jié)點的變化资铡。/tasks其下子節(jié)點存放待分配的任務电禀,而/assign則存放任務的分配情況。
. ZooKeeper內部原理
ZAB
?要理解ZooKeeper就必須要先理解ZAB這一部分內容比較多笤休,參考我寫的另外一篇文章ZAB協(xié)議尖飞。
請求處理
?Leader、Follower和Observer根本上都是服務器。我們在實現服務器時使
用的主要抽象概念是請求處理器政基。請求處理器是對處理流水線上不同階段的抽象贞铣。每一個服務器實現了一個請求處理器的序列。我們可以把一個處理器想象成添加到請求處理的一個元素沮明。一條請求經過服務器流水線上所有處理器的處理后被稱為得到完全處理辕坝。
請求處理器
?ZooKeeper代碼里有一個叫RequestProcessor的接口。這個接口的主要方法是processRequest荐健,它接受一個Request參數酱畅。在一條請求處理器的流水線上,對相鄰處理器的請求的處理通常通過隊列現實解耦合江场。當一個處理器有一條請求需要下一個處理器進行處理時纺酸,它將這條請求加入隊列。然后址否,它將處于等待狀態(tài)直到下一個處理器處理完此消息餐蔬。
Leader
- PrepRequestProcessor:接受客戶端的請求并執(zhí)行這個請求,處理結果則是生成一個事務在张。
- ProposalRequestProcessor:準備一個提議用含,并將該提議發(fā)送給跟隨者ProposalRequestProcessor將會把所有請求都轉發(fā)CommitRequestProcessor,而且帮匾,對于寫操作請求啄骇,還會將請求轉發(fā)給SyncRequestProcessor處理器。
- SyncRequestProcessor:負責將事務持久化到磁盤上瘟斜。實際上就是將事務數據按順序追加到事務日志中缸夹,并生成快照數據。
- AckRequestProcessor:一個簡單請求處理器螺句,它僅僅生成確認消息并返回給自己虽惭。
- CommitRequestProcessor:會將收到足夠多的確認消息的提議進行提交。
- ToBeAppliedRequestProcessor:這個處理器會從提議列表中刪除那些待接受的提議在FinalRequestProcessor處理器執(zhí)行后刪除這個列表中的元素蛇尚。
- FinalRequestProcessor:處理更新類型的請求芽唇,并執(zhí)行讀取請求。
Follower
- FollowerRequestProcessor :轉發(fā)請求給CommitRequestProcessor取劫,同時也會轉發(fā)寫請求到群首服務器匆笤。
- CommitRequestProcessor:直接轉發(fā)讀取請求到FinalRequestProcessor處理器,而且對于寫請求谱邪,為了保證執(zhí)行的順序炮捧,CommitRequestProcessor處理器會在收到一個寫請求處理器時暫停后續(xù)的請求處理,等待leader提交事務的消息惦银。
- SyncRequestProcessor:當leader接收到寫請求時會將提案發(fā)送給每個follower咆课,當收到一個提案末誓,follower會發(fā)送這個提議到SyncRequestProcessor處理器。
- SendRequestProcessor:會向群首發(fā)送確認消息书蚪。
小結
?平時工作中基本都是面向數據庫的CRUD喇澡,擁有很豐富的搬磚經驗,其實代碼的質量和水平并不高善炫。如果要實現一個雖然功能很簡單撩幽,但是要求可用性和拓展性很高組件,這時候感覺自己的水平就不夠用了箩艺。所以我們?yōu)槭裁匆タ匆恍﹥?yōu)秀的項目窜醉,也不是說每一段代碼都要掌握的很詳細,而是學習其中的思想艺谆。比如zookeeper其中服務狀態(tài)的轉換榨惰、服務之間的通信、FIFO隊列静汤、ZAB協(xié)議的實現琅催、對于請求處理器一個個的抽象、數據結構的設計等等虫给,這些都是可以從中學習到的思路藤抡。將來自己遇到類似的場景,想一想別人是怎么實現的抹估,自己腦子里才有思路缠黍,實現功能很簡單,最要的是如何實現的可維護药蜻、可拓展瓷式。當然zookeeper還有很多需要學習地方,本文只是對它做一個簡單的介紹和一些核心思想的實現進行說明语泽,大家想深入了ZooKeeper還是需要參考其他資料贸典。
參考
http://zookeeper.apache.org/
《從PAXOS到ZOOKEEPER分布式一致性原理與實踐》
《ZooKeeper:分布式過程協(xié)同技術詳解》
《Zab: A simple totally ordered broadcast protocol》