zookeeper 分布式服務架構是 apache hadoop 的一個子項目,
它主要是用來解決分布式應用中經常遇到的一些資料管理問題,如:統一命名服務、狀态同步服務、叢集管理、分布式應用配置項的管理等。
zookeeper 采用paxos一緻性算法保證了資料的一緻性,paxos算法是一種基于消息傳遞且具有高度容錯特性的一緻性算法。
想要更好的了解paxos算法,可以關注知乎的這個問題
<a href="http://www.zhihu.com/question/19787937" target="_blank">如何淺顯易懂地解說 paxos 的算法?</a>
zookeeper的核心是原子廣播,這個機制保證了各個server之間的同步。實作這個機制的協定叫做zab協定。zab協定有兩種模式,它們分别是恢複模式(選主)和廣播模式(同步)。當服務啟動或者在上司者崩潰後,zab就進入了恢複模式,當上司者被選舉出來,且大多數server完成了和leader的狀态同步以後,恢複模式就結束了。狀态同步保證了leader和server具有相同的系統狀态。
在分布式應用中,由于工程師不能很好地使用鎖機制,
以及基于消息的協調機制不适合在某些應用中使用,是以需要有一種可靠的、可擴充的、分布式的、可配置的協調機制來統一系統的狀态。
zookeeper緻力于下面的幾個目标:
最終一緻性:client不論連接配接到哪個server,展示給它都是同一個視圖,這是zookeeper最重要的性能。
可靠性:具有簡單、健壯、良好的性能,如果消息m被到一台伺服器接受,那麼它将被所有的伺服器接受。
實時性:
zookeeper保證用戶端将在一個時間間隔範圍内獲得伺服器的更新資訊,或者伺服器失效的資訊。但由于網絡延時等原因,zookeeper不能保證兩個用戶端能同時得到剛更新的資料,如果需要最新資料,應該在讀資料之前調用sync()接口。
等待無關(wait-free):
慢的或者失效的client不得幹預快速的client的請求,使得每個client都能有效的等待。
原子性:更新隻能成功或者失敗,沒有中間狀态。
順序性:包括全局有序和偏序兩種:全局有序是指如果在一台伺服器上消息a在消息b前釋出,則在所有server上消息a都将在消息b前被釋出;偏序是指如果一個消息b在消息a後被同一個發送者釋出,a必将排在b前面。
為了保證事務的順序一緻性,zookeeper采用了遞增的事務id号(zxid)來辨別事務。所有的提議(proposal)都在被提出的時候加上了zxid。實作中zxid是一個64位的數字,它高32位是epoch用來辨別leader關系是否改變,每次一個leader被選出來,它都會有一個新的epoch,辨別目前屬于那個leader的統治時期。低32位用于遞增計數。
每個server在工作過程中有三種狀态:
looking:目前server不知道leader是誰,正在搜尋
leading:目前server即為選舉出來的leader
following:leader已經選舉出來,目前server與之同步
(1)角色
zookeeper系統中的角色主要有三類,leader,learner和observer:

(2)選主流程
當leader崩潰或者leader失去大多數的follower,這時候zk進入恢複模式,恢複模式需要重新選舉出一個新的leader,讓所有的server都恢複到一個正确的狀态。
zk的選舉算法有兩種:一種是基于basic paxos實作的,另外一種是基于fast paxos算法實作的。
系統預設的選舉算法為fast paxos:
1.選舉線程由目前server發起選舉的線程擔任,其主要功能是對投票結果進行統計,并選出推薦的server;
2.選舉線程首先向所有server發起一次詢問(包括自己);
3.選舉線程收到回複後,驗證是否是自己發起的詢問(驗證zxid是否一緻),然後擷取對方的id(myid),并存儲到目前詢問對象清單中,最後擷取對方提議的leader相關資訊(id,zxid),并将這些資訊存儲到當次選舉的投票記錄表中;
4.收到所有server回複以後,就計算出zxid最大的那個server,并将這個server相關資訊設定成下一次要投票的server;
5.線程将目前zxid最大的server設定為目前server要推薦的leader,如果此時獲勝的server獲得n/2 + 1的server票數, 設定目前推薦的leader為獲勝的server,将根據獲勝的server相關資訊設定自己的狀态,否則,繼續這個過程,直到leader被選舉出來。
通過流程分析我們可以得出:要使leader獲得多數server的支援,則server總數必須是奇數2n+1,且存活的server的數目不得少于n+1.
每個server啟動後都會重複以上流程。在恢複模式下,如果是剛從崩潰狀态恢複的或者剛啟動的server還會從磁盤快照中恢複資料和會話資訊,zk會記錄事務日志并定期進行快照,友善在恢複時進行狀态恢複。選主的具體流程圖如下所示:
(3)同步流程
選完leader以後,zk就進入狀态同步過程。
1.leader等待server連接配接;
2.follower連接配接leader,将最大的zxid發送給leader;
3.leader根據follower的zxid确定同步點;
4.完成同步後通知follower 已經成為uptodate狀态;
5.follower收到uptodate消息後,又可以重新接受client的請求進行服務了。
(4)leader工作流程
leader主要有三個功能:
1.恢複資料;
2.維持與learner的心跳,接收learner請求并判斷learner的請求消息類型;
3.learner的消息類型主要有ping消息、request消息、ack消息、revalidate消息,根據不同的消息類型,進行不同的處理。
(5)follower工作流程
follower主要有四個功能:
1.向leader發送請求(ping消息、request消息、ack消息、revalidate消息);
2.接收leader消息并進行處理;
3.接收client的請求,如果為寫請求,發送給leader進行投票;
4.傳回client結果。