Zookeeper 是一個分佈式調度服務,用來解決分佈式系統中的統一調度問題。開發一個分佈式系統是一件很困難的事情,主要緣由就是由於咱們沒辦法去頗有效的處理分佈式系統中部分服務失敗的問題。在一個分佈式系統中,不一樣機器間是須要互相通訊的,而且由通訊方發起到被通訊方,而後結果要由被通訊方迴應。這時候假如被通訊方由於機房故障或者斷電網絡等一些因素,沒辦法通知,這樣通訊方就不知道發生了什麼,這樣整個集羣就發生了部分失敗的故障。Zookeeper 提供了一些工具可以讓分佈式應用安全合理的處理部分失敗的問題。php
Zookeeper 的運行有兩種方式,一種是 Standalone,還有一個就是 Replicated。這兩種的區別就是第一種只部署了單個節點,並且第二種就是以集羣的方式來部署。當以集羣來部署的時候,客戶端不須要鏈接全部的服務端,只須要鏈接其中一個就能夠得到一致性的讀寫服務。node
到 Apache Zookeeper 的下載頁面下載安裝包,而且解壓出來:shell
wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz tar -xzvf zookeeper-3.4.11.tar.gz cd zookeeper-3.4.11
啓動一個 Standalone 的服務很簡單,只須要一個配置文件而且放到 conf/zoo.cfg 下面便可,在 conf 目錄下 Zookeeper 已經有一個默認的文件了,直接複製過來便可,內容大概是這樣:apache
tickTime=2000 dataDir=/var/lib/zookeeper clientPort=2181
其中 tickTime 是基本時間單元,以毫秒爲單位,用來控制心跳和超時,默認狀況下最小的會話超時時間爲兩倍的 tickTime 。而後啓動:安全
bin/zkServer.sh start
每一個程序的第一步都是跑一個 HelloWorld,Zookeeper 也不例外,輸入如下的命令:服務器
echo ruok | nc localhost 2181
你應該會看到:網絡
imok
Zookeeper 的數據存儲就相似是一個文件系統,可是沒有文件和文件夾的概念,取而代之的是以 znode 來標示的。這個 znode 既是數據的容器,也是其餘節點的容器,也就是說 znode 能夠存儲數據和其餘 znode (能夠理解爲文件和文件夾,znode 就是文件夾,裏面的數據就是文件,惟一不一樣的是一個 znode 只能有一個數據,可是能夠有多個其餘的 znode),能夠看一下圖:分佈式
Zookeeper 自帶了一個命令行的客戶端,咱們能夠經過該命令行來操做一下,首先鏈接到 Zookeeper:工具
bin/zkCli.sh -server 127.0.0.1:2181
你應該能夠看到如下,而且光標一直在閃爍等待輸入,可使用 ls /
命令簡單操做一下。測試
Welcome to ZooKeeper! [zk: 127.0.0.1:2181(CONNECTED) 0]
在 Zookeeper 中,ZNode 能夠分爲持久節點和臨時節點兩類。持久節點是指一旦這個 ZNode 被建立了,除非主動進行刪除操做,不然將一直保存在ZooKeeper上;臨時節點就是和客戶端會話綁定,一旦客戶端斷開連接,那麼這個客戶端建立的全部臨時節點都會被移除。
[zkshell: 9] create /zk_test my_data Created /zk_test
其中的/zk_test
是 znode 的名字,my_data
是具體存儲的數據,建立成功以後能夠用 ls /
來查看一下:
[zkshell: 11] ls / [zookeeper, zk_test]
接下來,經過運行get命令來驗證數據是否與znode相關聯,以下所示:
[zkshell:12] get / zk_test my_data cZxid = 5 ctime = Fri Jun 05 13:57:06 PDT 2009 mZxid = 5 mtime = Fri Jun 05 13:57:06 PDT 2009 pZxid = 5 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0 dataLength = 7 numChildren = 0
[zkshell:14] set / zk_test junk [zkshell:15] get / zk_test junk
爲了方便閱讀,去除掉了部分無關的數據顯示。
接下來刪除掉剛纔建立的 znode,注意若是該 znode 下有其餘的 znode,則沒法刪除,必需要先把其餘的刪除了。
[zkshell:16] delete / zk_test [zkshell:17] ls / [zookeeper]
在開發和測試環境中咱們能夠以 Standalone 的方式來運行,可是若是要部署到生產環境那麼就應用以 Replicated 的方式來部署以得到更高的可用性。在該模式下至少須要三臺服務器,而且強烈建議要有一個奇數的服務器。若是你只有兩臺服務器,那麼就會有這樣一種狀況,若是其中一臺服務器出現故障,就會沒有足夠的機器來造成大多數投票決策,兩臺服務器本質上不如 一臺服務器穩定,由於有兩個單點故障。修改配置文件:
tickTime = 2000 dataDir = /var/lib/zookeeper clientPort = 2181 initLimit = 5 syncLimit = 2 server.1 = zoo1:2888:3888 server.2 = zoo2:2888:3888 server.3 = zoo3:2888:3888
若是有三臺機器的話,每臺機器都要這樣的配置。而後還要到/var/lib/zookeeper
新建一個myid
的文本文件,內容就是server.X
中的X
。接下來就能夠按照正常方式啓動了,啓動以後 Zookeeper 會自動投票選舉出一個 Leader,其餘的機器就是 Follower
在 Linux 的文件系統中,權限是以組和用戶來表示的,在 Zookeeper 有他本身的一套 ACL 權限用來控制客戶端的訪問權限(相似用戶對資源是否有讀寫權限),經過鑑權來得到客戶端的身份(相似帳號密碼登陸)。它自己的 ACL 機制是以 schemepermissions來表示的,第一個字段表示採用哪一種機制,第二個 id 表示用戶,permissions表示相關權限(如只讀,讀寫,管理等)。Zookeeper 總共提供了五中的 scheme :
只是 ACL 畢竟是簡單的訪問控制,並不是完整的權限管理,仍是有不少侷限性。好比 ACL 沒有繼承機制,全部的 ZNode 建立後都須要從新設置 ACL 而沒法繼承上一級的。
在對 ZooKeeper 有了一個簡單的瞭解之後,咱們就能夠用 Zookeeper 來構建一個簡單的配置管理服務。集羣中的機器能夠經過 ZooKeeper 共享一個通用的配置數據,而且能夠提供檢索和更新配置的服務,咱們會用 PHP 語言來實現。
PHP 在操做 Zookeeper 的時候是須要安裝一個擴展的,咱們能夠到 PECL 上面去下載。要注意的是該擴展要依賴一個 C 語言編寫的客戶端,Zookeeper 已經內置好了,進去 zookeeper-3.4.11/src/c
的目錄下,編譯安裝便可。
接下來咱們要新建一個 /config
的節點,把全部的配置都放到該節點下,很簡單:
[zkshell: 9] create /config my_data Created /config
咱們設計用 ZNode 來存儲配置的 key-value 鍵值對,咱們在 ZNode 中存儲一個 String 類型的數據做爲 value,用 ZNode 的 path 來表示 key。定義一個客戶端來讀取數據,而且經過 CLI 的方式運行起來,代碼不能再簡單了:
$zc = new Zookeeper(); $zc->connect('localhost:2181'); $path = '/config/key1'; $zc->get($path, function($i, $type, $key) use ($zc, $path){ echo $key."\n"; echo $zc->get($path); }); while(true){ echo ".\n"; sleep(1); }
而後經過 Zookeeper 自帶的命令行客戶端來修改一下配置:
切換回去 PHP CLI 的控制檯終端窗口應該就能夠看到:
咱們所實現的程序目前都是假設網絡穩定的狀況下實現的,可是一個真實的狀況是,網絡環境是會有不少緣由致使不穩定的。這裏不會講述如何正確的處理這些失敗,會在接下來的高級篇裏面在闡述。
歡迎關個人我的公衆號:左手代碼