ZooKeeper入門實戰教程(一)-介紹與核心概念

一、ZooKeeper介紹與核心概念
1.1 簡介
ZooKeeper最爲主要的使用場景,是做爲分佈式系統的分佈式協同服務。在學習zookeeper以前,先要對分佈式系統的概念有所瞭解,不然你將徹底不知道zookeeper在分佈式系統中起到了什麼做用,解決了什麼問題。node

 

1.2分佈式系統面臨的問題
咱們將分佈式系統定義爲:分佈式系統是同時跨越多個物理主機,獨立運行的多個軟件所組成系統。類比一下,分佈式系統就是一羣人一塊兒幹活。人多力量大,每一個服務器的算力是有限的,可是經過分佈式系統,由n個服務器組成起來的集羣,算力是能夠無限擴張的。數組

優勢顯而易見,人多幹活快,而且互爲備份。可是缺點也很明顯。咱們能夠想象一下,以一個小研發團隊開發軟件爲例,假設咱們有一個5人的項目組,要開始一個系統的開發,項目組將面臨以下問題:服務器

 

 

 

你必定在想,以上這些問題很簡單啊,在個人平常工做中每天都在發生,並沒感受有什麼複雜。是的,這是由於咱們人類的大腦是個超級計算機,可以靈活應對這些問題,並且現實中信息的交換不依賴網絡,不會因網絡延遲或者中斷,出現信息不對等。並且現實中對以上問題的處理其實並不嚴謹,從而也引起了不少問題。想想,項目中是否是出現過溝通不順暢形成任務分配有歧義?是否因爲人員離職形成任務進行不下去,甚至要聯繫離職人員協助?是否是出現過任務分配不合理?相似這樣的各類問題,確定會發生於你的項目組中。在現實世界,咱們能夠人爲去協調,即便出錯了,人工去補錯,加加班搞定就好。但在計算機的世界,這樣作是行不通的,一切都要保證嚴謹,以上問題要作到儘量不要發生。所以,分佈式系統必須採用合理的方式解決掉以上的問題。網絡

實際上要想解決這些問題並無那麼複雜,咱們僅須要作一件事就能夠萬事無憂---讓信息在項目組成員中同步。若是能作到信息同步,那麼每一個人在幹什麼,你們都是清楚的,幹到什麼程度也是清晰的,不管誰離職也不會產生問題。分配的工做,可以及時清晰的同步給每一個組員,確保每一個組員收到的任務分配沒有衝突。併發

分佈式系統的協調工做就是經過某種方式,讓每一個節點的信息可以同步和共享。這依賴於服務進程之間的通訊。通訊方式有兩種:負載均衡

一、經過網絡進行信息共享分佈式

這就像現實世界,開發leader在會上把任務傳達下去,組員經過聽leader命令或者看leader的郵件知道本身要幹什麼。當任務分配有變化時,leader會單獨告訴組員,或者再次召開會議。信息經過人與人之間的直接溝通,完成傳遞。svn

二、經過共享存儲學習

這就比如開發leader按照約定的時間和路徑,把任務分配表放到了svn上,組員天天去svn上拉取最新的任務分配表,而後幹活。其中svn就是共享存儲。更好一點的作法是,當svn文件版本更新時,觸發郵件通知,每一個組員再去拉取最新的任務分配表。這樣作更好,由於每次更新,組員都能第一時間獲得消息,從而讓本身手中的任務分配表永遠是最新的。此種方式依賴於中央存儲。整個過程以下圖所示:.net

 

 

 

 
1.3 ZooKeeper如何解決分佈式系統面臨的問題
ZooKeeper對分佈式系統的協調,使用的是第二種方式,共享存儲。其實共享存儲,分佈式應用也須要和存儲進行網絡通訊。網絡通訊是分佈式系統併發設計的基礎。

實際上,經過ZooKeeper實現分佈式協同的原理,和項目組經過SVN同步工做任務的例子是同樣的。ZooKeeper就像是svn,存儲了任務的分配、完成狀況等共享信息。每一個分佈式應用的節點就是組員,訂閱這些共享信息。當主節點(組leader),對某個從節點的分工信息做出改變時,相關訂閱的從節點獲得zookeeper的通知,取得本身最新的任務分配。完成工做後,把完成狀況存儲到zookeeper。主節點訂閱了該任務的完成狀況信息,因此將獲得zookeeper的完工的通知。參考下圖,回味一下,是否是和前面項目組經過svn分配工做的例子如出一轍?僅僅是把svn和郵件系統合二爲一,以ZooKeeper代替。

 

 

 

注:Slave節點要想獲取ZooKeeper的更新通知,需事先在關心的數據節點上設置觀察點。

大多數分佈式系統中出現的問題,都源於信息的共享出了問題。若是各個節點間信息不能及時共享和同步,那麼就會在協做過程當中產生各類問題。ZooKeeper解決協同問題的關鍵,在於保證分佈式系統信息的一致性。

經過以上章節的講解,咱們應該已經理解分佈式系統以及其面臨的問題。瞭解了ZooKeeper經過什麼樣的機制去解決這些問題。從宏觀上對ZooKeeper已經有了認知,接下來咱們先切入到zookeeper自身,講解zookeeper的概念,這些概念很重要,全部zookeeper的應用都會圍繞這些概念來實現。

 
1.四、zookeeper概念介紹
ZooKeeper並不直接暴露分佈式服務所須要的原語及原語的調用方法。什麼是原語?舉個例子,好比說分佈式鎖機制是一個原語,它會暴露出建立、獲取、釋放三個調用方法。ZooKeeper以相似文件系統的方式存儲數據,暴漏出調用這些數據的API。讓應用經過ZooKeeper的機制和API,本身來實現分佈式相關原語。

咱們若想讓應用可以經過ZooKeeper實現分佈式協同,那麼第一件事就是了解ZooKeeper的特性及相關概念,另外熟悉它給咱們提供了哪些API。

1.4.1 znode
第一章講過Zookeeper會保存任務的分配、完成狀況,等共享信息,那麼ZooKeeper是如何保存的呢?在ZooKeeper中,這些信息被保存在一個個數據節點上,這些節點被稱爲znode。它採用了相似文件系統的層級樹狀結構進行管理。見下圖示例:

 

 

 

根節點/包含4個子節點,其中三個擁有下一級節點。有的葉子節點存儲了信息。

節點上沒有存儲數據,也有着重要的含義。好比在主從模式中,當/master節點沒有數據時,表明分佈式應用的主節點尚未選舉出來。

znode節點存儲的數據爲字節數組。存儲數據的格式zookeeper不作限制,也不提供解析,須要應用本身實現。

實際上圖就是主從模式存儲數據的示例,這裏先簡單講解:

/master,存儲了當前主節點的信息
/workers,下面的每一個子znode表明一個從節點,子znode上存儲的數據,如「foo.com:2181」,表明從節點的信息。
/tasks,下面的每一個子znode表明一個任務,子znode上存儲的信息如「run cmd」,表明該內務內容
/assign,下面每一個子znode表明一個從節點的任務集合。如/assign/worker-1,表明worker-1這個從節點的任務集合。/assign/worker-1下的每一個子znode表明分配給worker-1的一個任務。
持久節點(persistent)和臨時節點(ephemeral)

持久節點只能經過delete刪除。臨時節點在建立該節點的客戶端崩潰或關閉時,自動被刪除。

前面例子中的/master應該使用臨時節點,這樣當主節點失效或者退出時,該znode被刪除,其餘節點知道主節點崩潰了,開始進行選舉的邏輯。另外/works/worker-1也應該是臨時節點,在此從節點失效的時候,該臨時節點自動刪除。

在目前的版本,因爲臨時znode會由於建立者會話過時被刪除,因此不容許臨時節點擁有子節點。

有序節點

znode能夠被設置爲有序(sequential)節點。有序znode節點被分配惟一一個單調遞增的證書。若是建立了個一有序節點爲/workers/worker-,zookeeper會自動分配一個序號1,追加在名字後面,znode名稱爲/workers/worker-1。經過這種方式,能夠建立惟一名稱znode,而且能夠直觀的看到建立的順序。

znode支持的操做及暴露的API:

create /path data

    建立一個名爲/path的znode,數據爲data。

delete /path

    刪除名爲/path的znode。

exists /path

    檢查是否存在名爲/path的znode

setData /path data

    設置名爲/path的znode的數據爲data

getData /path

    返回名爲/path的znode的數據

getChildren /path

    返回全部/path節點的全部子節點列表

1.4.2 觀察與通知
分佈式應用須要及時知道zookeeper中znode的變化,從而瞭解到分佈式應用總體的情況,若是採用輪詢方式,代價太大,絕大多數查詢都是無效的。所以,zookeeper採用了通知的機制。客戶端向zookeeper請求,在特定的znode設置觀察點(watch)。當該znode發生變化時,會觸發zookeeper的通知,客戶端收到通知後進行業務處理。觀察點觸發後當即失效。因此一旦觀察點觸發,須要再次設置新的觀察點。

咱們使用Zookeeper不能指望可以監控到節點每次的變化。思考以下場景:

一、客戶端C1設置觀察點在/tasks

二、觀察點觸發,C1處理本身的邏輯

三、C1設置新的觀察點前,C2更新了/tasks

四、C1處理完邏輯,再次設置了觀察點。

此時C1不會獲得第三步的通知,所以錯過了C2更新/tasks此次操做。要想不錯過此次更新,C1須要在設置監視點前讀取/tasks的數據,進行對比,發現更新。

再以下面的場景:

一、客戶端C1設置觀察點在/tasks

二、/tasks上發生了連續兩次更新

三、C1在獲得第一次更新的通知後就讀取了/tasks的數據

四、此時第二次更新也已經發生,C1用第一次的通知,讀取到兩次更新後的數據

此時C1雖然錯過了第二次通知,可是C1最終仍是讀取到了最新的數據。

所以Zookeeper只能保證最終的一致性,而沒法保證強一致性。

zookeeper能夠定義不一樣的觀察類型。例如觀察znode數據變化,觀察znode子節點變化,觀察znode建立或者刪除。

1.4.3 版本
每一個znode都有版本號,隨着每次數據變化自增。setData和delete,以版本號做爲參數,當傳入的版本號和服務器上不一致時,調用失敗。當多個zookeeper客戶端同時對一個znode操做時,版本將會起到做用,假設c1,c2同時往一個znode寫數據,c1先寫完後版本從1升爲2,可是c2寫的時候攜帶版本號1,c2會寫入失敗。

1.4.4 法定人數
zookeeper服務器運行於兩種模式:獨立模式和仲裁模式(集羣)。仲裁模式下,會複製全部服務器的數據樹。但若是讓客戶端等待全部複製完成,延遲過高。這裏引入法定人數概念,指爲了使zookeeper集羣正常工做,必須有效運行的服務器數量。同時也是服務器通知客戶端保存成功前,必須保存數據的服務器最小數。例如咱們有一個5臺服務器的zookeeper集羣,法定人數爲3,只要任何3個服務器保存了數據,客戶端就會收到確認。只要有3臺服務器存活,整個zookeeper集羣就是可用的。

下圖展現了客戶端提交請求到收到回覆的過程:

 

 

 

法定人數須要大於服務器數量的一半。也稱爲多數原則。舉個例子說明,假如集羣有5臺服務器,法定人數爲2,那麼有2臺服務器參與複製便可,若這2臺server剛剛複製完/z這個znode,就掛掉了。此時剩下了3臺server,大於法定人數2,因此zookeeper認爲集羣正常,但這三臺服務器是沒法發現/z這個znode的。若是法定人數大於服務器數量一半,那麼法定人數複製完成,就能夠確保集羣存活時,至少有一臺服務器有最新的znode,不然集羣認爲本身已經崩潰。

下面兩個例子闡明瞭,爲什麼要遵循多數原則。

下圖展現了5臺server,法定人數爲3,在確保zookeeper集羣存活的前提下,最壞的狀況掛了2臺server(剩餘及器數量3>=法定人數3),zookeeper是如何能確保數據完備,集羣繼續工做的。

 

 

 

接下來兩張圖展現了5臺server,未遵循多數原則,法定人數設爲2。一樣掛了兩臺server時,爲何zookeeper集羣會出問題。

首先,客戶端發起請求,2個server複製數據後即返回客戶端接收成功。

 

 

 

就在此刻,很不幸,在繼續同步更新給其餘節點前,剛剛兩個複製了數據的節點掛了。此時會怎樣呢?以下圖:

 

 

 

能夠看到建立/z的操做在zookeeper集羣中丟失了。

相信經過以上講解,你已經可以理解爲何法定人數必定要多於一半服務器的數量。

此外,咱們要儘可能選用奇數個服務器,這樣集羣能容忍崩潰服務器佔比更大,性價比更高。例如4臺服務器的集羣,法定人數最少爲3,那麼只能容許1臺服務器崩潰,也就是僅容許25%的機器崩潰。而5臺服務器的集羣,法定人數最少也是3,可是此時容許2臺服務器崩潰。換句話講,40%的機器崩潰後還能工做。

仲裁模式下,負載均衡經過客戶端隨機選擇鏈接串中的某個服務器來實現。

 
1.4.5 會話
客戶端對zookeeper集羣發送任何請求前,須要和zookeeper集羣創建會話。客戶端提交給zookeeper的全部操做均關聯在一個會話上。當一個會話因某種緣由終止時,會話期間建立的臨時節點將會消失。而噹噹前服務器的問題,沒法繼續通訊時,會話將被透明的轉移到另一臺zookeeper集羣的服務器上。

會話提供了順序保障。同一個會話中的請求以FIFO順序執行。併發會話的FIFO順序沒法保證。

 
1.4.6 會話狀態和生命週期
會話狀態有:

connecting、connected、closed、not_connected

建立會話時,須要設置會話超時這個重要的參數。若是通過時間t後服務接受不到這個會話的任何消息,服務就會聲明會話過時。客戶端側,t/3時間未收到任何消息,客戶端向服務器發送心跳消息,2t/3時間後,客戶端開始尋找其餘服務器。此時他有t/3的時間去尋找,找不到的話,會話失效。

重連服務器時,只有更新大於客戶端的服務器才能被鏈接,以避免鏈接到落後的服務器。zookeeper中經過更新創建的順序,分配事務標識符。只有服務器的事物標識符大於客戶端攜帶的標識符時,纔可鏈接。————————————————版權聲明:本文爲CSDN博主「稀有氣體」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/liyiming2017/article/details/83035157

相關文章
相關標籤/搜索