ZooKeeper入門指南
入門:使用Zookeeper協調分佈式應用
該文檔的內容能夠使你學會快速使用Zookeeper.文檔主要針對希望嘗試它的開發人員,它包含如何安裝一個單機Zookeeper服務的安裝說明,一些驗證正在運行的命令,一個簡單編程例子. 最後,爲了方便,關於一些複雜的安裝,例如集羣運行部署,優化事務日誌.關於商業的完整安裝文檔,請參考 ZooKeeper Administrator's Guide.
知識儲備
查看用戶指南中的系統要求.
下載
從Apache鏡像中下載一個最新穩定的版本.
單機配置
安裝單機Zookeeper是非常簡單的. 服務包含一個獨立的Jar文件,所以只需要創一個配置文件.
一旦你下載了穩定的Zookeeper版本,解壓它並使用cd去根目錄使用一個配置文件啓動它. 這是一個例子,創建在 conf/zoo.cfg:
tickTime=2000 dataDir=/var/lib/zookeeper clientPort=2181
這個文件可以被稱爲任何名稱,但是爲了能夠說明那它就稱它爲conf/zoo.cfg. 可以通過改變dataDir的值 去指明一個存在的目錄. 這兒是每一個字段的含義:
- tickTime
tickTime是最基本的時間單元,使用毫秒爲時間單位.它被使用來作爲心跳檢測和最小的會話超時時間,是tickTime時間的兩倍.
- dataDir
這個地址用來存儲內存數據庫的快照,除非特別聲明,事務文件也會存儲在該位置.
- clientPort
這個端口用來監聽連接客戶端連接.
現在你已經創建了配置文件,你可以開啓Zookeeper.
bin/zkServer.sh start
ZooKeeper日誌信息使用log4j -- 在程序員指南日誌部分有更多詳細信息.你將會看到日誌文件輸出到控制檯(默認配置)或者在log4j配置日誌文件地址查看.
主要講單機模式運行Zookeeper的步驟. 這裏沒有使用集羣配置,所以如果Zookeeper一旦出現處理異常,服務將會停止.這對於大部分情況下都是可以接收的,如果要在集羣環境下運行,請查看 Running Replicated ZooKeeper.
管理Zookeeper存儲
對於正式長時間運行的Zookeeper存儲系統必須進行外部管理(數據文檔和日誌).查閱更多詳細信息,請查看維護部分.
連接Zookeeper
$ bin/zkCli.sh -server 127.0.0.1:2181
這個操作執行很簡單,看起來像是文件操作.
只要你已經連接了Zookeeper,你看到下面這些信息:
Connecting to localhost:2181 log4j:WARN No appenders could be found for logger (org.apache.zookeeper.ZooKeeper). log4j:WARN Please initialize the log4j system properly. Welcome to ZooKeeper! JLine support is enabled [zkshell: 0]
來到shell,輸入help你可以獲得一個可以在客戶端執行的命令清單,例如:
[zkshell: 0] help ZooKeeper host:port cmd args get path [watch] ls path [watch] set path data [version] delquota [-n|-b] path quit printwatches on|off createpath data acl stat path [watch] listquota path history setAcl path acl getAcl path sync path redo cmdno addauth scheme auth delete path [version] setquota -n|-b val path
由此,你可以嘗試一些簡單的命令來熟悉命令行接口. First, start by issuing the list command, as in ls, yielding:
[zkshell: 8] ls / [zookeeper]
接下來,接下來通過create /zk_test my_data創建一個新的節點. 創建的新節點包含一個String類型的節點數據.你可以看到如下這樣:
[zkshell: 9] create /zk_test my_data Created /zk_test
可以通過ls命令查看目錄下節點,例如:
[zkshell: 11] ls / [zookeeper, zk_test]
現在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
我們可以執行set命令改變zk_test節點的關聯數據,例如:
[zkshell: 14] set /zk_test junk cZxid = 5 ctime = Fri Jun 05 13:57:06 PDT 2009 mZxid = 6 mtime = Fri Jun 05 14:01:52 PDT 2009 pZxid = 5 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0 dataLength = 4 numChildren = 0 [zkshell: 15] get /zk_test junk cZxid = 5 ctime = Fri Jun 05 13:57:06 PDT 2009 mZxid = 6 mtime = Fri Jun 05 14:01:52 PDT 2009 pZxid = 5 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0 dataLength = 4 numChildren = 0
(我們在設置數據後,獲取該數據驗證,發現確實發生了改變,最後讓我們來刪除該節點.)
[zkshell: 16] delete /zk_test [zkshell: 17] ls / [zookeeper] [zkshell: 18]
以上內容到這裏爲止.如果需要查閱文檔更多的剩餘內容,請查看Programmer's Guide.
ZooKeeper編程
ZooKeeper可以使用Java語言和C語言兩種編程方式. 它們是功能等價的.C語言僅有兩個不通電:單線程和多線程.這個不同點只會在消息循環時提現出來.更多信息,請查看 Programming Examples in the ZooKeeper Programmer's Guide 使用不同API的例子.
運行集羣Zookeeper
運行單機Zookeeper有利於方便的評估、開發、測試.但在正式環境,應該運行集羣Zookeeper. 同一個應用的服務組我們稱之爲集羣. 在集羣模式下,所有服務都可以複製同樣的配置.
在集羣模式,至少應有3臺服務器,強烈推薦你使用奇數個服務器.如果你僅有兩臺服務器,一旦其中一臺出現故障,你講沒有足夠的機器組成集羣.兩臺機器比一臺機器天生就有更多的不穩定的可能,因爲存在兩個故障點.
集羣模式和單機模式都需要使用的conf/zoo.cfg文件,但是有一些地方不一樣.例子:
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
新配置條目, initLimit 是集羣中其他機器連接leader的超時時間限制.syncLimit是一個服務器無法訪問leader的最大時間限制.
這兩個時間限制值,都是基於時間單元tickTime值設置的.例如,initLimit是5 tick,在tick值是2000毫秒的情況下,該值是10秒.
上面的配置文件中的表單服務條目(指server.1=zoo1:2888:3888,server.2=zoo2:2888:3888,server.3=zoo3:2888:3888這些配置).由server.X組成Zookeeper服務.當服務啓動時,會通過查找zookeeper/data目錄下的myid文件,來查找它屬於那個服務. 這個文件包含一個ASCCII編碼的服務編號.
最後,需要注意每個服務名稱後面都會跟兩個端口號:" 2888" 和 "3888". 服務器之間通過前一個端口號互相連接.因爲各個服務器間需要互相通信,所以相互連接是必要的,例如用來協調服務更新順序. 更確切的解釋是,一個Zookeeper服務通過該端口連接follower至leader. 當一個新的leader產生時,follower使用該端口打開TCP連接leader.因爲默認的leader選舉也使用TCP,我們一般爲leader選舉使用另外一個端口,這就是服務條目中的第二個端口的作用.
如果你想要在一臺服務器是運行集羣服務,可以在每個服務配置文件的server.X中,將集羣的servername設置爲localhost & 設置各個(例如:i.e. 2888:3888, 2889:3889, 2890:3890),各個服務的dataDirs和clientPort必須獨立. (在上面的集羣配置例子中,雖然在同一臺localhost機器上運行集羣,但你仍然需要三個配置文件).
請注意,在一臺機器上運行集羣不會有冗餘效果.如果發生意外情況導致機器掛掉,全部Zookeeper服務都將掛掉.完全冗餘效果需要每一個服務都有屬於自己的服務器.並且必須是獨立的物理服務器.單臺物理機器上的多個虛擬機同樣也會容易因種種意外造成服務全部掛掉.
其他優化
還有一些其他配置能夠大大提高性能:
爲了獲得服務更新的低延遲,建立專門的事物日誌目錄是必要的.默認的事物日誌目錄與數據快照和myid文件是同一個目錄.dataLogDir 參數用於設置新的事物日誌目錄.
[tbd: 其他配置參數還有那些?]