一步到位分布式開發Zookeeper實現集群管理


  說到分布式開發Zookeeper是必須了解和掌握的,分布式消息服務kafka 、hbase 到hadoop等分布式大數據處理都會用到Zookeeper,所以在此將Zookeeper作為基礎來講解。

   Zookeeper 是分布式服務框架,主要是用來解決分布式應用中經常遇到的一些數據管理問題,如:統一命名服務、狀態同步服務、集群管理、分布式應用配置項的管理等等。

  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與之同步。

 

  ZooKeeper的安裝模式分為三種,分別為:單機模式、集群模式和集群偽分布模式

環境

  CentOS7.0  (windows中使用就使用zkServer.cmd)

  ZooKeeper最新版本

  用root用戶安裝(如果用於hbase時將所有文件權限改為hadoop用戶)

     Java環境,最好是最新版本的。

  分布式時多機間要確保能正常通訊,關閉防火牆或讓涉及到的端口通過。

下載

  去官網下載 :http://zookeeper.apache.org/releases.html#download

  下載后放進CentOS中的/usr/local/ 文件夾中,並解壓到當前文件中 /usr/local/zookeeper(怎么解壓可參考之前的Haproxy的安裝文章)

安裝

單機模式

  進入zookeeper目錄下的conf子目錄, 重命名 zoo_sample.cfg文件,Zookeeper 在啟動時會找這個文件作為默認配置文件:

mv /usr/local/zookeeper/conf/zoo_sample.cfg  zoo.cfg

  配置zoo.cfg參數

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=/usr/local/zookeeper/data
dataLogDir=/usr/local/zookeeper/log
# the port at which the clients will connect
clientPort=2181
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
#http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

參數說明:

tickTime:毫秒值.這個時間是作為 Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。
dataDir:顧名思義就是 Zookeeper 保存數據的目錄,默認情況下,Zookeeper 將寫數據的日志文件也保存在這個目錄里。
dataLogDir:顧名思義就是 Zookeeper 保存日志文件的目錄
clientPort:這個端口就是客戶端連接 Zookeeper 服務器的端口,Zookeeper 會監聽這個端口,接受客戶端的訪問請求。

  再創建上面配置的data和log文件夾:

mkdir  /usr/local/zookeeper/data
mkdir  /usr/local/zookeeper/log

啟動zookeeper

  先進入/usr/local/zookeeper文件夾

cd /usr/local/zookeeper

  再運行 

bin/zkServer.sh start

  檢測是否成功啟動:執行

bin/zkCli.sh 
或 
echo stat|nc localhost 2181

 

 偽集群模式

  所謂偽集群, 是指在單台機器中啟動多個zookeeper進程, 並組成一個集群. 以啟動3個zookeeper進程為例,模擬3台機。
  將zookeeper的目錄多拷貝2份:
  zookeeper/conf/zoo.cfg文件與單機一樣,只改為下面的內容:

tickTime=2000 
initLimit=5 
syncLimit=2 
dataDir=/usr/local/zookeeper/data
dataLogDir=/usr/local/zookeeper/log
clientPort=2180
server.0=127.0.0.1:2888:3888
server.1=127.0.0.1:2889:3889 
server.2=127.0.0.1:2890:3890

  新增了幾個參數, 其含義如下:

1 initLimit: zookeeper集群中的包含多台server, 其中一台為leader, 集群中其余的server為follower. initLimit參數配置初始化連接時, follower和leader之間的最長心跳時間. 此時該參數設置為5, 說明時間限制為5倍tickTime, 即5*2000=10000ms=10s.
2 syncLimit: 該參數配置leader和follower之間發送消息, 請求和應答的最大時間長度. 此時該參數設置為2, 說明時間限制為2倍tickTime, 即4000ms.
3 server.X=A:B:C 其中X是一個數字, 表示這是第幾號server. A是該server所在的IP地址. B配置該server和集群中的leader交換消息所使用的端口. C配置選舉leader時所使用的端口. 由於配置的是偽集群模式, 所以各個server的B, C參數必須不同.
參照zookeeper/conf/zoo.cfg, 配置zookeeper1/conf/zoo.cfg, 和zookeeper2/conf/zoo.cfg文件. 只需更改dataDir, dataLogDir, clientPort參數即可.

在之前設置的dataDir中新建myid文件, 寫入一個數字, 該數字表示這是第幾號server. 該數字必須和zoo.cfg文件中的server.X中的X一一對應.
/usr/local/zookeeper/data/myid文件中寫入0, /usr/local/zookeeper1/data/myid文件中寫入1, /Users/apple/zookeeper2/data/myid文件中寫入2.

  分別進入/usr/local/zookeeper/bin, /usr/local/zookeeper1/bin, /usr/local/zookeeper2/bin三個目錄, 啟動server。啟動方法與單機一致。

bin/zkServer.sh start

  分別檢測是否成功啟動:執行

bin/zkCli.sh 
或 
echo stat|nc localhost 2181

 

集群模式

  集群模式的配置和偽集群基本一致.
  由於集群模式下, 各server部署在不同的機器上, 因此各server的conf/zoo.cfg文件可以完全一樣.
  下面是一個示例:

tickTime=2000 
initLimit=5 
syncLimit=2 
dataDir=/usr/local/zookeeper/data
dataLogDir=/usr/local/zookeeper/log
clientPort=2180
server.0=192.168.80.30:2888:3888
server.1=192.168.80.31:2888:3888
server.2=192.168.80.32:2888:3888

  示例中部署了3台zookeeper server, 分別部署在192.168.80.30, 192.168.80.31, 192.168.80.32上. 

  需要注意的是, 各server的dataDir目錄下的myid文件中的數字必須不同,192.168.80.30 server的myid為0, 192.168.80.31 server的myid為1, 192.168.80.32 server的myid為2

  分別進入/usr/local/zookeeper/bin目錄, 啟動server。啟動方法與單機一致。

bin/zkServer.sh start

  分別檢測是否成功啟動:執行

bin/zkCli.sh 
或 
echo stat|nc localhost 2181

   這時會報大量錯誤?其實沒什么關系,因為現在集群只起了1台server,zookeeper服務器端起來會根據zoo.cfg的服務器列表發起選舉leader的請求,因為連不上其他機器而報錯,那么當我們起第二個zookeeper實例后,leader將會被選出,從而一致性服務開始可以使用,這是因為3台機器只要有2台可用就可以選出leader並且對外提供服務(2n+1台機器,可以容n台機器掛掉)。

 

ZooKeeper服務命令

1. 啟動ZK服務: zkServer.sh start
2. 查看ZK服務狀態: zkServer.sh status
3. 停止ZK服務: zkServer.sh stop
4. 重啟ZK服務: zkServer.sh restart

 

zk客戶端命令:

  ZooKeeper 命令行工具類似於Linux的shell環境,使用它可以對ZooKeeper進行訪問,數據創建,數據修改等操作.

  使用 zkCli.sh -server 192.168.80.31:2181 連接到 ZooKeeper 服務,連接成功后,系統會輸出 ZooKeeper 的相關環境以及配置信息。命令行工具的一些簡單操作如下:

1. 顯示根目錄下、文件: ls / 使用 ls 命令來查看當前 ZooKeeper 中所包含的內容
2. 顯示根目錄下、文件: ls2 / 查看當前節點數據並能看到更新次數等數據
3. 創建文件,並設置初始內容: create /zk "test" 創建一個新的 znode節點“ zk ”以及與它關聯的字符串
4. 獲取文件內容: get /zk 確認 znode 是否包含我們所創建的字符串
5. 修改文件內容: set /zk "zkbak" 對 zk 所關聯的字符串進行設置
6. 刪除文件: delete /zk 將剛才創建的 znode 刪除
7. 退出客戶端: quit
8. 幫助命令: help

 擴展

  通過上述命令實踐,我們可以發現,zookeeper使用了一個類似文件系統的樹結構,數據可以掛在某個節點上,可以對這個節點進行刪改。另外我們還發現,當改動一個節點的時候,集群中活着的機器都會更新到一致的數據。 

zookeeper的數據模型

  在簡單使用了zookeeper之后,我們發現其數據模型有些像操作系統的文件結構,結構如下圖所示

(1)     每個節點在zookeeper中叫做znode,並且其有一個唯一的路徑標識,如/SERVER2節點的標識就為/APP3/SERVER2
(2)     Znode可以有子znode,並且znode里可以存數據,但是EPHEMERAL類型的節點不能有子節點
(3)     Znode中的數據可以有多個版本,比如某一個路徑下存有多個數據版本,那么查詢這個路徑下的數據就需要帶上版本。
(4)     znode 可以是臨時節點,一旦創建這個 znode 的客戶端與服務器失去聯系,這個 znode 也將自動刪除,Zookeeper 的客戶端和服務器通信采用長連接方式,每個客戶端和  服務器通過心跳來保持連接,這個連接狀態稱為 session,如果 znode 是臨時節點,這個 session 失效,znode 也就刪除了
(5)     znode 的目錄名可以自動編號,如 App1 已經存在,再創建的話,將會自動命名為 App2 
(6)     znode 可以被監控,包括這個目錄節點中存儲的數據的修改,子節點目錄的變化等,一旦變化可以通知設置監控的客戶端,這個功能是zookeeper對於應用最重要的特性,通過這個特性可以實現的功能包括配置的集中管理,集群管理,分布式鎖等等。  

 選舉流程

  當 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會記錄事務日志並定期進行快照,方便在恢復時進行狀態恢復。 

應用場景

   是指通過指定的名字來獲取資源或者服務的地址,提供者的信息。利用Zookeeper很容易創建一個全局的路徑,而這個路徑就可以作為一個名字,它可以指向集群中的集群,提供的服務的地址,遠程對象等。簡單來說使用Zookeeper做命名服務就是用路徑作為名字,路徑上的數據就是其名字指向的實體。

  阿里巴巴集團開源的分布式服務框架Dubbo中使用ZooKeeper來作為其命名服務,維護全局的服務地址列表。在Dubbo實現中:
服務提供者在啟動的時候,向ZK上的指定節點/dubbo/${serviceName}/providers目錄下寫入自己的URL地址,這個操作就完成了服務的發布。
服務消費者啟動的時候,訂閱/dubbo/{serviceName}/providers目錄下的提供者URL地址, 並向/dubbo/{serviceName} /consumers目錄下寫入自己的URL地址。
  注意,所有向ZK上注冊的地址都是臨時節點,這樣就能夠保證服務提供者和消費者能夠自動感應資源的變化。
  另外,Dubbo還有針對服務粒度的監控,方法是訂閱/dubbo/{serviceName}目錄下所有提供者和消費者的信息。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM