Zookeeper入門看這篇就夠了

Zookeeper是什麼

官方文檔上這麼解釋zookeeper,它是一個分佈式服務框架,是Apache Hadoop 的一個子項目,它主要是用來解決分佈式應用中經常遇到的一些數據管理問題,如:統一命名服務、狀態同步服務、集羣管理、分佈式應用配置項的管理等。

上面的解釋有點抽象,簡單來說zookeeper=文件系統+監聽通知機制。

1、 文件系統

Zookeeper維護一個類似文件系統的數據結構:



每個子目錄項如 NameService 都被稱作爲 znode(目錄節點),和文件系統一樣,我們能夠自由的增加、刪除znode,在一個znode下增加、刪除子znode,唯一的不同在於znode是可以存儲數據的。

有四種類型的znode:

  • PERSISTENT-持久化目錄節點

    客戶端與zookeeper斷開連接後,該節點依舊存在

  • PERSISTENT_SEQUENTIAL-持久化順序編號目錄節點

    客戶端與zookeeper斷開連接後,該節點依舊存在,只是Zookeeper給該節點名稱進行順序編號

  • EPHEMERAL-臨時目錄節點

    客戶端與zookeeper斷開連接後,該節點被刪除

  • EPHEMERAL_SEQUENTIAL-臨時順序編號目錄節點

    客戶端與zookeeper斷開連接後,該節點被刪除,只是Zookeeper給該節點名稱進行順序編號

2、 監聽通知機制

客戶端註冊監聽它關心的目錄節點,當目錄節點發生變化(數據改變、被刪除、子目錄節點增加刪除)時,zookeeper會通知客戶端。

就這麼簡單,下面我們看看Zookeeper能做點什麼呢?

Zookeeper能做什麼

zookeeper功能非常強大,可以實現諸如分佈式應用配置管理、統一命名服務、狀態同步服務、集羣管理等功能,我們這裏拿比較簡單的分佈式應用配置管理爲例來說明。

假設我們的程序是分佈式部署在多臺機器上,如果我們要改變程序的配置文件,需要逐臺機器去修改,非常麻煩,現在把這些配置全部放到zookeeper上去,保存在 zookeeper 的某個目錄節點中,然後所有相關應用程序對這個目錄節點進行監聽,一旦配置信息發生變化,每個應用程序就會收到 zookeeper 的通知,然後從 zookeeper 獲取新的配置信息應用到系統中。


如上,你大致應該瞭解zookeeper是個什麼東西,大概能做些什麼了,我們馬上來學習下zookeeper的安裝及使用,並開發一個小程序來實現zookeeper這個分佈式配置管理的功能。

Zookeeper單機模式安裝

Step1:配置JAVA環境,檢驗環境:java -version

Step2:下載並解壓zookeeper

# cd /usr/local# wget http://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz# tar -zxvf zookeeper-3.4.12.tar.gz# cd zookeeper-3.4.12

Step3:重命名配置文件zoo_sample.cfg

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

Step4:啓動zookeeper

# bin/zkServer.sh start

Step5:檢測是否成功啓動,用zookeeper客戶端連接下服務端

# bin/zkCli.sh

Zookeeper使用

使用客戶端命令操作zookeeper

1、使用 ls 命令來查看當前 ZooKeeper 中所包含的內容



2、創建一個新的 znode ,使用 create /zkPro myData


3、再次使用 ls 命令來查看現在 zookeeper 中所包含的內容:


4、下面我們運行 get 命令來確認第二步中所創建的 znode 是否包含我們所創建的字符串:


5、下面我們通過 set 命令來對 zk 所關聯的字符串進行設置:


6、下面我們將剛纔創建的 znode 刪除


使用Java API操作zookeeper

使用Java API操作zookeeper需要引用下面的包


下面我們來實現上面說的分佈式配置中心:

1、在zookeeper裏增加一個目錄節點,並且把配置信息存儲在裏面

2、啓動兩個zookeeper客戶端程序,代碼如下所示

import java.util.concurrent.CountDownLatch;import org.apache.zookeeper.WatchedEvent;import org.apache.zookeeper.Watcher;import org.apache.zookeeper.Watcher.Event.EventType;import org.apache.zookeeper.Watcher.Event.KeeperState;import org.apache.zookeeper.ZooKeeper;import org.apache.zookeeper.data.Stat;/** * 分佈式配置中心demo * @author  * */public class ZooKeeperProSync implements Watcher {private static CountDownLatch connectedSemaphore = new CountDownLatch(1);private static ZooKeeper zk = null;private static Stat stat = new Stat();public static void main(String[] args) throws Exception {//zookeeper配置數據存放路徑String path = "/username";//連接zookeeper並且註冊一個默認的監聽器zk = new ZooKeeper("192.168.31.100:2181", 5000, //new ZooKeeperProSync());//等待zk連接成功的通知connectedSemaphore.await();//獲取path目錄節點的配置數據,並註冊默認的監聽器System.out.println(new String(zk.getData(path, true, stat)));Thread.sleep(Integer.MAX_VALUE);}public void process(WatchedEvent event) {if (KeeperState.SyncConnected == event.getState()) {  //zk連接成功通知事件if (EventType.None == event.getType() && null == event.getPath()) {connectedSemaphore.countDown();} else if (event.getType() == EventType.NodeDataChanged) {  //zk目錄節點數據變化通知事件try {System.out.println("配置已修改,新值爲:" + new String(zk.getData(event.getPath(), true, stat)));} catch (Exception e) {}}}}}

兩個程序啓動後都正確的讀取到了zookeeper的/username目錄節點下的數據'qingfeng'

3、我們在zookeeper裏修改下目錄節點/username下的數據


修改完成後,我們看見兩個程序後臺都及時收到了他們監聽的目錄節點數據變更後的值,如下所示


Zookeeper集羣模式安裝

本例搭建的是僞集羣模式,即一臺機器上啓動三個zookeeper實例組成集羣,真正的集羣模式無非就是實例IP地址不同,搭建方法沒有區別

Step1:配置JAVA環境,檢驗環境:java -version

Step2:下載並解壓zookeeper

# cd /usr/local# wget http://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz# tar -zxvf zookeeper-3.4.12.tar.gz# cd zookeeper-3.4.12

Step3:重命名 zoo_sample.cfg文件

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

Step4:修改配置文件zoo-1.cfg,原配置文件裏有的,修改成下面的值,沒有的則加上

# vim conf/zoo-1.cfgdataDir=/tmp/zookeeper-1clientPort=2181server.1=127.0.0.1:2888:3888server.2=127.0.0.1:2889:3889server.3=127.0.0.1:2890:3890

配置說明

  • 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 實例通信端口號不能一樣,所以要給它們分配不同的端口號。

Step4:再從zoo-1.cfg複製兩個配置文件zoo-2.cfg和zoo-3.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.cfgdataDir=/tmp/zookeeper-2clientPort=2182# vim conf/zoo-2.cfgdataDir=/tmp/zookeeper-3clientPort=2183

Step5:標識Server ID

創建三個文件夾/tmp/zookeeper-1,/tmp/zookeeper-2,/tmp/zookeeper-2,在每個目錄中創建文件myid 文件,寫入當前實例的server id,即1.2.3

# cd /tmp/zookeeper-1# vim myid1# cd /tmp/zookeeper-2# vim myid2# cd /tmp/zookeeper-3# vim myid3

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服務端檢測


至此,我們對zookeeper就算有了一個入門的瞭解,當然zookeeper遠比我們這裏描述的功能多,比如用zookeeper實現集羣管理,分佈式鎖,分佈式隊列,zookeeper集羣leader選舉等等


文章來源:https://my.oschina.net/u/3796575/blog/1845035


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