官方文檔上這麼解釋zookeeper,它是一個分佈式服務框架,是Apache Hadoop 的一個子項目,它主要是用來解決分佈式應用中常常遇到的一些數據管理問題,如:統一命名服務、狀態同步服務、集羣管理、分佈式應用配置項的管理等。html
上面的解釋有點抽象,簡單來講zookeeper=文件系統+監聽通知機制。java
一、 文件系統node
Zookeeper維護一個相似文件系統的數據結構:apache
每一個子目錄項如 NameService 都被稱做爲 znode(目錄節點),和文件系統同樣,咱們可以自由的增長、刪除znode,在一個znode下增長、刪除子znode,惟一的不一樣在於znode是能夠存儲數據的。小程序
有四種類型的znode:vim
PERSISTENT-持久化目錄節點服務器
客戶端與zookeeper斷開鏈接後,該節點依舊存在微信
PERSISTENT_SEQUENTIAL-持久化順序編號目錄節點數據結構
客戶端與zookeeper斷開鏈接後,該節點依舊存在,只是Zookeeper給該節點名稱進行順序編號框架
EPHEMERAL-臨時目錄節點
客戶端與zookeeper斷開鏈接後,該節點被刪除
EPHEMERAL_SEQUENTIAL-臨時順序編號目錄節點
客戶端與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
一、使用 ls 命令來查看當前 ZooKeeper 中所包含的內容
二、建立一個新的 znode ,使用 create /zkPro myData
三、再次使用 ls 命令來查看如今 zookeeper 中所包含的內容:
四、下面咱們運行 get 命令來確認第二步中所建立的 znode 是否包含咱們所建立的字符串:
五、下面咱們經過 set 命令來對 zk 所關聯的字符串進行設置:
六、下面咱們將剛纔建立的 znode 刪除
使用Java API操做zookeeper須要引用下面的包
下面咱們來實現上面說的分佈式配置中心:
一、在zookeeper裏增長一個目錄節點,而且把配置信息存儲在裏面
二、啓動兩個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'
三、咱們在zookeeper裏修改下目錄節點/username下的數據
修改完成後,咱們看見兩個程序後臺都及時收到了他們監聽的目錄節點數據變動後的值,以下所示
本例搭建的是僞集羣模式,即一臺機器上啓動三個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.cfg dataDir=/tmp/zookeeper-1 clientPort=2181 server.1=127.0.0.1:2888:3888 server.2=127.0.0.1:2889:3889 server.3=127.0.0.1:2890:3890
配置說明
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.cfg dataDir=/tmp/zookeeper-2 clientPort=2182 # vim conf/zoo-2.cfg dataDir=/tmp/zookeeper-3 clientPort=2183
Step5:標識Server ID
建立三個文件夾/tmp/zookeeper-1,/tmp/zookeeper-2,/tmp/zookeeper-2,在每一個目錄中建立文件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服務端檢測
至此,咱們對zookeeper就算有了一個入門的瞭解,固然zookeeper遠比咱們這裏描述的功能多,好比用zookeeper實現集羣管理,分佈式鎖,分佈式隊列,zookeeper集羣leader選舉等等,想要深刻學習的同窗能夠掃下方二維碼關注微信公號"輕風吟",完整的源碼回覆"zk入門"獲取
官方文檔:http://zookeeper.apache.org/doc/r3.4.12/index.html
參考書籍:《從Paxos到Zookeeper 分佈式一致性原理與實踐》