ZooKeeper

參考:

https://www.jianshu.com/p/01388f06e75d

https://www.cnblogs.com/iforever/p/9095095.html

1.zookeeper是什麼

分佈式應用程序的分佈式協調服務。分佈式應用程序可以基於它實現同步服務,配置維護和命名服務等。

1.1角色

2.解決什麼

當在一個集羣規模的環境中,多臺同類型的應用使用同樣的配置文件,爲了避免登陸每臺機器修改配置,爲了減少人爲的修改導致配置不一致,爲了實現配置文件的統一管理、版本控制,那麼就有必要實現一個配置管理中心的應用。

3.用途及設計目的

  數據發佈與訂閱(配置中心)
  負載均衡
  命名服務(Naming Service)
  分佈式通知/協調
  集羣管理與Master選舉
  分佈式鎖
  分佈式隊列

1.最終一致性:client不論連接到哪個Server,展示給它都是同一個視圖,這是zookeeper最重要的性能。

2 .可靠性:具有簡單、健壯、良好的性能,如果消息m被到一臺服務器接受,那麼它將被所有的服務器接受。

3 .實時性:Zookeeper保證客戶端將在一個時間間隔範圍內獲得服務器的更新信息,或者服務器失效的信息。但由於網絡延時等原因,Zookeeper不能保證兩個客戶端能同時得到剛更新的數據,如果需要最新數據,應該在讀數據之前調用sync()接口。

4 .等待無關(wait-free):慢的或者失效的client不得干預快速的client的請求,使得每個client都能有效的等待。

5.原子性:更新只能成功或者失敗,沒有中間狀態。

6 .順序性:包括全局有序和偏序兩種:全局有序是指如果在一臺服務器上消息a在消息b前發佈,則在所有Server上消息a都將在消息b前被髮布;偏序是指如果一個消息b在消息a後被同一個發送者發佈,a必將排在b前面。

4.擔保

ZooKeeper非常快速而且非常簡單。但是,由於其目標是構建更復雜的服務(如同步)的基礎,
因此它提供了一系列保證:
  順序一致性 - 客戶端的更新將按發送順序應用。
  原子性 - 更新成功或失敗。沒有部分結果。
  單系統映像 - 無論服務器連接到哪個服務器,客戶端都將看到相同的服務視圖。
  可靠性 - 一旦應用了更新,它將從那時起持續到客戶端覆蓋更新。
  及時性 - 系統的客戶視圖保證在特定時間範圍內是最新的。

5.部署

linux:https://www.cnblogs.com/wrong5566/p/6056788.html,https://blog.51cto.com/ityunwei2017/2131509

windows:https://blog.csdn.net/shengqianfeng/article/details/79297171

6.配置管理

6.1實現了哪些功能

0. 標準的key value的配置文件幾個
1. 基於web頁面的配置文件的增刪改查
2. 同一個app下多個配置文件
3. 版本管理,當前版本,歷史版本管理
4. 數據持久化保存
5. 非標準的key value配置文件的管理
6. 客戶端watcher的實現

6.2同類型的配置方案

1. 王阿晶,鄒仕洪: [基於ZooKeeper的配置信息存儲方案的設計與實現](http://wenku.baidu.com/view/ee86ca90daef5ef7ba0d3c7d.html)
2. 淘寶diamod實現:[http://code.taobao.org/p/diamond/src/](http://code.taobao.org/p/diamond/src/), 2012
3. disconf github: [https://github.com/knightliao/disconf](https://github.com/knightliao/disconf), 2014
4. [百度BJF配置中心](http://wiki.babel.baidu.com/twiki/bin/view/Main/CAP-CC#%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%831.0%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97.pptx), 2014

6.3原理

zookeeper提供了節點watch的功能,zookeeper的client(對外提供服務的server)監控zookeeper上的節點(znode),當節點變動的時候,client會收到變動事件和變動後的內容,基於zookeeper的這個特性,我們可以給服務器集羣中的所有機器(client)都註冊watch事件,監控特定znode,節點中存儲部署代碼的配置信息,需要更新代碼的時候,修改znode中的值,服務器集羣中的每一臺server都會收到代碼更新事件,然後觸發調用,更新目標代碼。也可以很容易的橫向擴展,可以隨意的增刪機器,機器啓動的時候註冊監控節點事件即可。

配合上git的hook機制,可以做一個完整的系統,當代碼有更新的時候更新保存代碼信息znode上的數據,zookeeper push到所有watch這個節點的服務器,服務器更新代碼,所有服務器完成一次更新操作。

7.服務發現

7.1原理

註冊一個持久節點/service/business/what,他下面的每個子節點都是一個可用服務,保存了服務的地址端口等信息,服務調用者通過zookeeper獲取/service/business/what所有子節點信息來得到可用的服務。下面的節點都是臨時節點,服務器啓動的時候會過來註冊一個臨時節點,服務器掛掉之後或主動關閉之後,臨時節點會自動移除,這樣就可以保證使用者獲取的what服務都是可用的,而且可以動態的擴容縮容。

 

除此之外,還可以在從zookeeper獲取可用服務列表的時候加一層緩存,提高性能,額外一個進程watch/service/business/what的子節點變動,當有子節點變動的時候,刪除緩存,這樣就可以做到緩存中的內容'時時'和zookeeper中保持一致了

8.zk在kafka中的作用

在kafka中,zookeeper負責的是存儲kafka中的元數據信息,隊列的數據是不會存儲到zookeeper的,kafka是分佈式的,zookeeper協調broker、producer、consumer之間的關係,當有新的角色加入的時候,更新zookeeper中的數據,其他角色就可以得到通知,並作出相應的調整,不需要停機更新配置,做到動態擴容。下圖來自互聯網,比較清晰的展示了zookeeper中存儲的kafka元信息數據。

9.zookeeper如何實現負載均衡的?

zookeeper 的數據存儲類似於liunx的目錄結構。首先建立servers節點,並建立監聽器監視servers子節點的狀態(用於在服務器增添時及時同步當前集羣中服務器列表)。在每個服務器啓動時,在servers節點下建立子節點worker server(可以用服務器地址命名),並在對應的字節點下存入服務器的相關信息。這樣,我們在zookeeper服務器上可以獲取當前集羣中的服務器列表及相關信息,可以自定義一個負載均衡算法,在每個請求過來時從zookeeper服務器中獲取當前集羣服務器列表,根據算法選出其中一個服務器來處理請求。

參考:

https://blog.csdn.net/u010523770/article/details/63685353

https://blog.csdn.net/justry_deng/article/details/84790782

https://blog.csdn.net/dshf_1/article/details/81087447

服務器負載均衡有三大基本特徵:負載均衡算法,健康檢查和會話保持,這三個特徵是保證負載均衡正常工作的基本要素。

9.1負載均衡算法

Ø  輪詢(RoundRobin)將請求順序循環地發到每個服務器。當其中某個服務器發生故障,AX就把其從順序循環隊列中拿出,不參加下一次的輪詢,直到其恢復正常。

Ø  比率(Ratio):給每個服務器分配一個加權值爲比例,根椐這個比例,把用戶的請求分配到每個服務器。當其中某個服務器發生故障,AX就把其從服務器隊列中拿出,不參加下一次的用戶請求的分配,直到其恢復正常。

Ø  優先權(Priority):給所有服務器分組,給每個組定義優先權,將用戶的請求分配給優先級最高的服務器組(在同一組內,採用預先設定的輪詢或比率算法,分配用戶的請求);當最高優先級中所有服務器或者指定數量的服務器出現故障,AX將把請求送給次優先級的服務器組。這種方式,實際爲用戶提供一種熱備份的方式。

Ø  最少連接數(LeastConnection):AX會記錄當前每臺服務器或者服務端口上的連接數,新的連接將傳遞給連接數最少的服務器。當其中某個服務器發生故障,AX就把其從服務器隊列中拿出,不參加下一次的用戶請求的分配,直到其恢復正常。

Ø  最快響應時間(Fast Reponse time):新的連接傳遞給那些響應最快的服務器。當其中某個服務器發生故障,AX就把其從服務器隊列中拿出,不參加下一次的用戶請求的分配,直到其恢復正常。

以上爲通用的負載均衡算法,還有一些算法根據不同的需求也可能會用到,例如:

Ø  哈希算法( hash):  將客戶端的源地址,端口進行哈希運算,根據運算的結果轉發給一臺服務器進行處理,當其中某個服務器發生故障,就把其從服務器隊列中拿出,不參加下一次的用戶請求的分配,直到其恢復正常。

Ø  基於策略的負載均衡:針對不同的數據流設置導向規則,用戶可自行編輯流量分配策略,利用這些策略對通過的數據流實施導向控制。

Ø  基於數據包的內容分發:例如判斷HTTP的URL,如果URL中帶有.jpg的擴展名,就把數據包轉發到指定的服務器。

9.2健康檢查

健康檢查用於檢查服務器開放的各種服務的可用狀態。創建健康檢查時可以設定檢查的間隔時間和嘗試次數,例如設定間隔時間爲5秒,嘗試次數爲3,那麼負載均衡設備每隔5秒發起一次健康檢查,如果檢查失敗,則嘗試3次,如果3次都檢查失敗,則把該服務標記爲DOWN,然後服務器仍然會每隔5秒對DOWN的服務器進行檢查,當某個時刻發現該服務器健康檢查又成功了,則把該服務器重新標記爲UP。健康檢查的間隔時間和嘗試次數要根據綜合情況來設置,原則是既不會對業務產生影響,又不會對負載均衡設備造成較大負擔。

9.3會話保持

會話保持用於保持會話的連續性和一致性,由於服務器之間很難做到實時同步用戶訪問信息,這就要求把用戶的前後訪問會話保持到一臺服務器上來處理。負載均衡設備一般會默認配置一些會話保持的選項,例如源地址的會話保持,Cookie會話保持等,基於不同的應用要配置不同的會話保持,否則會引起負載的不均衡甚至訪問異常。

10.zk命名服務

參考:https://blog.csdn.net/weixin_33772645/article/details/87002758

主要兩點吧:節點類似於文件系統中的目錄結構、可以創建順序節點

11.zk實現分佈式通知/協調

https://blog.csdn.net/en_joker/article/details/78799737

ZooKeeper中特有的Watcher註冊與異步通知機制,能夠很好的實現分佈式環境下不同機器,甚至是不同系統之間的協調與通知,從而實現對數據變更的實時處理。

基於ZooKeeper實現分佈式協調與通知功能,從而實現對數據變更的實時處理。基於ZooKeeper實現分佈式協調與通知功能,通常的做法是不同的客戶端都對ZooKeeper上同一個數據節點進行Watcher註冊,監聽數據節點的變化(包括數據節點本身及其子節點),如果數據節點發生變化,那麼所有訂閱的客戶端都能夠接收到相應的Watcher通知,並做出相應的處理。

12.zk實現分佈式鎖

https://blog.csdn.net/sunfeizhi/article/details/51926396

12.1分佈式鎖介紹

分佈式鎖主要用於在分佈式環境中保護跨進程、跨主機、跨網絡的共享資源實現互斥訪問,以達到保證數據的一致性。

12.2獲取分佈式鎖的總體思路

 在獲取分佈式鎖的時候在持久節點下創建臨時順序節點,釋放鎖的時候刪除該臨時節點。

1.客戶端調用createNode方法在持久節點下創建臨時順序節點

2.然後調用getChildren(“locker”)來獲取持久節點下面的所有子節點,注意此時不用設置任何Watcher。客戶端獲取到所有的子節點path之後,

3.如果發現自己在之前創建的子節點序號最小,那麼就認爲該客戶端獲取到了鎖。

4.如果發現自己創建的節點並非locker所有子節點中最小的,說明自己還沒有獲取到鎖,此時客戶端需要找到比自己小的那個節點,然後對其調用exist()方法,同時對其註冊事件監聽器。之後,讓這個被關注的節點刪除,則客戶端的Watcher會收到相應通知,此時再次判斷自己創建的節點是否是locker子節點中序號最小的,如果是則獲取到了鎖,如果不是則重複以上步驟繼續獲取到比自己小的一個節點並註冊監聽。當前這個過程中還需要許多的邏輯判斷。

13.Zookeeper分佈式隊列的實現

原文:https://blog.csdn.net/evankaka/article/details/70806752

Zookeeper可以處理兩種類型的隊列:
(1)同步隊列
當一個隊列的成員都聚齊時,這個隊列纔可用,否則一直等待所有成員到達。

思路:在zookeeper中先創建一個根目錄 queue_sync,做爲隊列隊列的消費者監視/queue/start節點,剛開始還沒有這個節點,所以什麼都不會做。入隊操作就是在queue_sync下創建子節點,然後計算子節點的總數,看是否和隊列的目標數量相同。如果相同,創建/queue_sync/start節點,由於/queue_sync/start這個節點有了狀態變化,zookeeper就會通知監視者:隊員已經到齊了,監視者得到通知後進行自己的後續流程
(2)先進先出隊列
按照FIFO方式進行入隊和出隊

思路:在zookeeper中先創建一個根目錄 queue_fifo,做爲隊列。入隊操作就是在queue_fifo下創建自增序的子節點,並把數據放入節點內。出隊操作就是先找到queue_fifo下序號最下的那個節點,取出數據,然後刪除此節點。

14工作原理

Zookeeper的核心是原子廣播,這個機制保證了各個Server之間的同步。實現這個機制的協議叫做Zab協議。Zab協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步)。當服務啓動或者在領導者崩潰後,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和leader的狀態同步以後,恢復模式就結束了。狀態同步保證了leader和Server具有相同的系統狀態。

爲了保證事務的順序一致性,zookeeper採用了遞增的事務id號(zxid)來標識事務。所有的提議(proposal)都在被提出的時候加上了zxid。實現中zxid是一個64位的數字,它高32位是epoch用來標識leader關係是否改變,每次一個leader被選出來,它都會有一個新的epoch,標識當前屬於那個leader的統治時期。低32位用於遞增計數。

每個Server在工作過程中有三種狀態:

  • LOOKING:當前Server不知道leader是誰,正在搜尋

  • LEADING:當前Server即爲選舉出來的leader

  • FOLLOWING:leader已經選舉出來,當前Server與之同步

14.1選主流程

leader崩潰或者leader失去大多數的follower,這時候zk進入恢復模式,恢復模式需要重新選舉出一個新的leader,讓所有的Server都恢復到一個正確的狀態。Zk的選舉算法有兩種:一種是基於basic paxos實現的,另外一種是基於fast paxos算法實現的。系統默認的選舉算法爲fast paxos。先介紹basic 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會記錄事務日誌並定期進行快照,方便在恢復時進行狀態恢復選主的具體流程圖如下所示:

fast paxos流程是在選舉過程中,某Server首先向所有Server提議自己要成爲leader,當其它Server收到提議以後,解決epoch和zxid的衝突,並接受對方的提議,然後向對方發送接受提議完成的消息,重複這個流程,最後一定能選舉出Leader。其流程圖如下所示:

14.2 同步流程

選完leader以後,zk就進入狀態同步過程。

  1. leader等待server連接;

  2. Follower連接leader,將最大的zxid發送給leader;

  3. Leader根據follower的zxid確定同步點;

  4. 完成同步後通知follower 已經成爲uptodate狀態;

  5. Follower收到uptodate消息後,又可以重新接受client的請求進行服務了。

流程圖如下所示:

14.3 Leader工作流程

Leader主要有三個功能:

  1. 恢復數據

  2. 維持與Learner的心跳,接收Learner請求並判斷Learner的請求消息類型;

  3. Learner的消息類型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根據不同的消息類型,進行不同的處理。

PING消息是指Learner的心跳信息;REQUEST消息是Follower發送的提議信息,包括寫請求及同步請求;ACK消息是Follower的對提議的回覆,超過半數的Follower通過,則commit該提議;REVALIDATE消息是用來延長SESSION有效時間。
Leader的工作流程簡圖如下所示,在實際實現中,流程要比下圖複雜得多,啓動了三個線程來實現功能。

14.4 Follower工作流程

Follower主要有四個功能:

  1. 1. 向Leader發送請求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);

  2. 2 .接收Leader消息並進行處理;

  3. 3 .接收Client的請求,如果爲寫請求,發送給Leader進行投票;

  4. 4 .返回Client結果

Follower的消息循環處理如下幾種來自Leader的消息:

  1. 1 .PING消息: 心跳消息;

  2. 2 .PROPOSAL消息:Leader發起的提案,要求Follower投票;

  3. 3 .COMMIT消息:服務器端最新一次提案的信息;

  4. 4 .UPTODATE消息:表明同步完成;

  5. 5 .REVALIDATE消息:根據Leader的REVALIDATE結果,關閉待revalidate的session還是允許其接受消息;

  6. 6 .SYNC消息:返回SYNC結果到客戶端,這個消息最初由客戶端發起,用來強制得到最新的更新。

Follower的工作流程簡圖如下所示,在實際實現中,Follower是通過5個線程來實現功能的。

對於observer的流程不再敘述,observer流程和Follower的唯一不同的地方就是observer不會參加leader發起的投票。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章