zookeeper是一個分布式程序的高性能協調服務,提供集中式信息存儲服務,數據存儲於內存中,類似文件系統的樹形結構,高吞吐量和低延時,集群高可靠,基於zookeeper可以實現分布式統一配置中心、分布式鎖、服務注冊中心。
zookeeper的同類產品 consul etcd Doozer等
單機版安裝
下載tar文件,地址 http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.14/
解壓后在conf目錄增加zoo.cfg(復制zoo_sample.cfg文件,重命名即可),注意配置data的路徑
啟動服務端 進入zookeeper安裝目錄 bin/zkServer.sh start
客戶端連接 bin/zkCli.sh -server 127.0.0.1:2181
zookeeper常用命令,參考 https://zookeeper.apache.org/doc/current/zookeeperStarted.html ,輸出help即可看到
在安裝包下有 zookeeper-3.4.14.jar,它就是官方提供的java 客戶端,我們可以使用它來操作zookeeper,但是其api太過底層,所以一般使用第三方的客戶端,常用的有zkClient和Curator。
zookeeper核心概念
1、session
一個客戶端連接是一個會話,由zk分布一個唯一id 客戶端以特定的時間發送心跳保持會話,ticktime,超過會話超時時間未收到心跳則判定客戶端掛掉,(默認2倍ticktime),會話中的請求FIFO執行
2、數據模型
節點類型
持久節點 create /asd asd
臨時節點 create -e /asd asd 連接斷開后即消失
順序節點 create -s /asd asd 真實名稱asd0000000268(名字+ 10位十進制數字)
順序節點 create -s /asd/ asd 真實名稱0000000268(10位十進制數字)
臨時順序節點 create -s -e /asd asd
節點數據構成:存儲的協調信息和元數據,數據量上限1M
節點元數據結構:zxid(事務id)
3、zookeeper中的時間
Zxid zookeeper種每一次更改操作都對應一個唯一的事務id,稱為zxid,它是全局有序的戳記,如果zxid1>zxid2,則zxid1一定在zxid2之后發生
version number 每次對節點的修改都會使其版本號增加
ticktime 在使用多服務器時,服務器通過ticktime來定義事件的時間,ticktime僅通過最小會話時間(ticktime的2倍)公開,如果客戶端請求的會話時間小於最小會話時間,則服務器會告訴客戶端會話超時實際上為最小超時時間
real time 僅在znode創建和修改時將時間戳放入stat結構中
4、watch監聽機制
通過help命令我們可以看到ls get 等命令都支持watch,命令使用如下 get /asd 1(boolean值,默認為0,為1時表示監控變化)。watch機制是一次性觸發,即只能監控到第一次的變化,若要持續監控,則需要持續設置watch,watch是有序的,客戶端先收到watch通知后看到變化。
因為watch是一次性的,並且在獲取通知和發送新的watch請求存在間隙,所以不能可靠的發現節點的每一次變化
使用場景
1、配置中心
主要使用到zookeeper的兩個特性,znode存儲數據及watch機制,兩種使用方式:一個配置項一個znode和一個配置文件一個znode,具體看配置在集群中的差異性。
2、命名服務
分布式開發中A服務不依賴B服務的具體ip端口信息,而是根據一個服務名去獲取對應的ip端口信息,這樣A服務可以先行部署而后監聽B服務對應的服務名的變化,而后B服務開發完工后再部署后,A服務不用做任何修改就可以正常訪問,具體如下圖
3、master選舉
兩種方式:
(1)爭搶創建主節點,集群中各個服務器在申請創建同一個主節點(臨時節點)時帶上自己的地址信息,但是只有一個會創建成功,其它的創建失敗后則后通過獲取主節點的值來知道當前主節點是誰,並且注冊對主節點的watch,當master掛掉后,對應的主節點也被刪除,此時剩下的服務器則又開始新一輪的爭搶創建主節點,創建成功的即為下一個master。
(2)集群各個服務器都申請創建臨時順序節點,序號最小的即為master,master掛掉后其后一個節點對應的機器則為master。
同時還可以創建一個server節點,所有集群中的節點都來創建一個一個臨時順序節點,利用這個可以做集群管理
4、分布式隊列
入隊:所有生產者往同一個節點下(queue)創建順序節點
出隊:獲取節點下所有子節點,移除最小序號對應的節點
針對無界隊列,可以利用上面所說直接實現,有界隊列則需要用到分布式所來實現獲取隊列元素數目和放入元素同步
5、分布式鎖
兩種方式
(1)都去創建同名臨時節點,創建成功則執行后續邏輯,沒有創建成功則注冊這個節點的watch
(2)創建同名臨時順序節點,獲取所有子節點,判斷自己是否為最小號,是則獲取鎖成功執行邏輯后刪除對應節點,不是則注冊前一個節點的watch等待被通知