Spring Cloud 微服務學習筆記04 服務治理 Zookeeper基礎

1.   Zookeeper

    1.1 Zookeeper 概述

    Zookeeper是應用於分佈式應用程序的高性能分佈式協調服務,它暴露了一組簡單的公共服務(提供java和C接口),如命名、配置管理、集羣服務、分佈式鎖等,分佈式應用程序可以基於此實現更高級別的服務進行同步、組合命名。

   1.1.1 Zookeeper作用

    配置管理

在微服務架構中,往往存在諸多配置,有很多服務都需要這些配置,這時就需要一種集中管理配置,我們在集中管理的地方變更配置,對這個配置感興趣的服務都能獲得變更。Zookeeper提供集中管理配置方法使用Zab(Zookeeper Atomic Broadcast 原子廣播)這種一致性協議來提供一致性。目前需要開源框架使用Zookeeper維護配置,比如HBase、Kafka、Dubbo。

    命名服務

Zookeeper提供統一的入口,方便維護微服務架構中應用地址。

    集羣管理

在分佈式的集羣中,經常因爲各種原因,比如硬件故障、網絡問題、軟件故障等,有些節點會進進出出。有新的節點加入集羣,也有老的節點退出集羣。這個時候集羣其他機器需要感知這個變化,然後根據這個變化做出相應決策。例如一個分佈式存儲系統,有個中央節點負責存儲分配,當有新的存儲進來需要根據集羣狀態來分配存儲節點,這時就需要動態感知集羣狀態;又如分佈式SOA架構中,消費者需要訪問某個服務時,需要某種機制發現那些節點可以提供服務(這也稱爲服務發現)。alibaba 開源分佈式SOA架構Dubbo使用Zookeeper作爲服務發現的底層機制,Kafka隊列也是使用Zookeeper作爲Customer服務的上下線管理。

    分佈式鎖

    1.1.2 Zookeeper存儲結構

    命名空間

    Zookeeper允許分佈式進程通過類似文件系統的共享分層命名空間相互協調。命名空間由Zookeeper語法中數據寄存器(Znodes)組成,這類似文件和目錄。Zookeeper數據保存在內存中,Zookeeper可以實現高吞吐量和低延遲數。

    Zookeeper分層命名空間:

Zookeeper名稱是以反斜槓(/)分隔的路徑元素序列。Zookeeper名稱空間每個節點都由路徑標識。

    節點和短暫節點

    和標準文件系統不一樣,Zookeeper每個節點(Znode)都有與其相關聯的數據和子節點,就好像是一個允許文件也是目錄的文件系統。Zookeeper設計爲存儲協調數據:狀態信息、配置、位置信息等,存儲在每個節點的數據都很小。

    Znodes維護統計結構,其中包括數據更改、ACL更改和時間戳的版本號,以緩存驗證和協調更新。每次Znode節點更新,Znodes版本號都會增加。

    存儲在Znode節點的數據以原子的方式讀取和寫入,獲取和Znode相關所有數據,寫入替換所有數據。每個節點都有一個訪問控制列表(ACL),它限制誰能做什麼。

    Zookeeper還存短暫節點的概念。只要創建的Znode的會話處於活動狀態,就會存在,當會話結束,Znode就會刪除。

    有條件的更新和觀察者Watcher

    Zookeeper 支持觀察者概念。客戶端可以在Znode上設置觀察者(Watcher),當Znode更改時,觀察者將被觸發並移除。當觀察者觸發時,客戶端接收到一個數據包,說明Znode已經改變了。

    提供應用唯一標識

    Zookeeper集羣中,每個節點需要唯一標識,這個唯一標識要求是自然數,且唯一標識保存位置是:$dataDir/myid,其中 dataDir 爲配置文件 zoo.cfg 中的配置參數 在 data 目錄中創建文件 myid : touch myid 爲應用提供唯一標識。

    1.2 Zookeeper原理

   Zookeeper和協調的分佈式進程一樣,其本身也是被複制到一組被稱爲合奏的主機上,Zookeeper服務的服務間互相瞭解,他們維護的內存映射以及持久存儲的事務和日誌快照。只要Zookeeper大部分服務器可用,Zookeeper服務可用。

   Zoopeeper由一個

    客戶端Client連接到Zookeeper服務器,客戶端維持TCP聯繫,通過它發送請求和獲取響應,獲取Watcher時間併發送心跳。如果客戶端TCP連接中斷,將連接到其他服務器。

    Zookeeper組件顯示Zookeeper的高級服務組件。除了請求處理器外,組成Zookeeper服務的每個服務器都會複製其每個組件的副本。

Zookeeper組件:

複製的數據庫包含整個數據樹的內存數據庫。將更新記錄到磁盤已獲得可恢復性,並將序列化到磁盤,然後才能應用到內存數據庫。

    Zookeeper每個服務器都爲客戶端服務,客戶端所有寫入請求都轉發到單個服務器,稱爲主管/領導者。其他稱爲學習者/關注者的Zookeeper服務器從領導者接受消息提議,並同意消息傳遞。Zookeeper使用自定義的原子消息協議。由於協議是原子的,所有Zookeeper可以保證本地副本不會發散。

   Zookeeper集羣中主要分爲三大類角色:

  •    領導者-負責投票的發起和決議,更新系統狀態;
  •    學習者/關注者

     跟隨者-接收客戶端請求並返回響應,在選主過程參與投票;

    觀察者-接收客戶端連接,將寫請求轉發給leader節點,但觀察者不參與投票,只同步leader狀態。觀察者目的是擴展系統,提高讀取速度。

  •     客戶端-請求發起方  

   1.3 Zookeeper特性及設計目的

  • 順序性:客戶端的更新將按照發送的順序進行應用。
  • 原子性:更新結果只有成功和失敗,沒有中間狀態。
  • 最終一致性/單一系統映像-客戶端無論連接那個Server,展示給它的都是同一視圖。
  • 可靠性:具有簡單、健壯、良好的性能,一旦應用更新了,將從當前持續到客戶端覆蓋更新。
  • 實時性:系統的客戶端在一定時間保證是最新的。

   1.4. 使用Zookeeper協調分佈式應用

    1.4.1 Zookeeper安裝

    單機模式安裝

     Step1:下載解壓縮並重命名cfg 

官網下載後需要修改\zookeeper-xxx\conf文件夾下zoo_sample.cfg文件名稱爲zoo.cfg

    Step2: 啓動Zookeeper

    \zookeeper-xxx\conf\bin\zkServer.sh start

    Step3:檢查啓動是否成功,使用Zookeeper客戶端連接下服務器

    集羣模式安裝

    Step1:下載並解壓縮

    Step2:重命名\zookeeper-xxx\conf文件夾下zoo_sample.cfg

# cp conf/zoo_sample.cfg conf/zoo-1.cfg

    Step3:修改cfg配置,設置服務、投票、選舉端口

# vim conf/zoo-1.cfg
tickTime = 2000 
dataDir = /var/lib/zookeeper1 
clientPort = 2181 
initLimit = 5 
syncLimit = 2 
#服務端口根據應用做對應修改
server.1 = zoo1:2888:3888 
server.2 = zoo2:2888:3888
server.3 = zoo3:2888:3888

    Step4:複製zoo.cfg出來兩個zoo1.cfg和zoo2.cfg,修改對應的dataDir和clientPort即可

# cp conf/zoo-1.cfg conf/zoo-2.cfg
# cp conf/zoo-1.cfg conf/zoo-3.cfg
# vim conf/zoo-2.cfg
dataDir=/tmp/zookeeper-2
clientPort=2182
# vim conf/zoo-2.cfg
dataDir=/tmp/zookeeper-3
clientPort=2183

    Step5:標識Server ID,創建三個目錄,在每個目錄創建myid文件,寫入當前實例Server ID,即1、2、3

# cd /tmp/zookeeper-1
# vim myid
1
# cd /tmp/zookeeper-2
# vim myid
2
# cd /tmp/zookeeper-3
# vim myid
3

    Step6: 分別啓動Zookeeper三個實例

# bin/zkServer.sh start conf/zoo-1.cfg
# bin/zkServer.sh start conf/zoo-2.cfg
# bin/zkServer.sh start conf/zoo-3.cfg

    Step7:檢查集羣狀態,使用命令“zkCli.sh -server IP:PORT” 連接Zookeeper服務檢測

     安裝配置說明

  • tickTime:這個時間是作爲 Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。
  • initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這裏所說的客戶端不是用戶連接 Zookeeper 服務器的客戶端,而是 Zookeeper 服務器集羣中連接到 Leader 的 Follower 服務器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過 10個心跳的時間(也就是 tickTime)長度後 Zookeeper 服務器還沒有收到客戶端的返回信息,那麼表明這個客戶端連接失敗。總的時間長度就是 10*2000=20 秒
  • syncLimit:這個配置項標識 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 5*2000=10秒
  • dataDir:顧名思義就是 Zookeeper 保存數據的目錄,默認情況下,Zookeeper 將寫數據的日誌文件也保存在這個目錄裏。
  • clientPort:這個端口就是客戶端連接 Zookeeper 服務器的端口,Zookeeper 會監聽這個端口,接受客戶端的訪問請求。
  • server.A=B:C:D:其中 A 是一個數字,表示這個是第幾號服務器;B 是這個服務器的 ip 地址;C 表示的是這個服務器與集羣中的 Leader 服務器交換信息的端口;D 表示的是萬一集羣中的 Leader 服務器掛了,需要一個端口來重新進行選舉,選出一個新的 Leader,而這個端口就是用來執行選舉時服務器相互通信的端口。如果是僞集羣的配置方式,由於 B 都是一樣,所以不同的 Zookeeper 實例通信端口號不能一樣,所以要給它們分配不同的端口號。

     需要注意Zookeeper集羣模式,至少需要三臺服務,強烈建議奇數個服務。如果是兩臺服務器,那麼在Leader出現故障後,則沒有足夠機器形成大多數法定人數,從而無法選舉出新的Leader。兩臺服務本身比單機模式穩定,因爲有兩個單點故障。

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