Alex 的 Hadoop 菜鳥教程: 第9課 zookeeper 介紹和使用
阿新 • • 發佈:2019-01-30
- ZooKeeper是一個分散式的,開放原始碼的分散式應用程式協調服務。
- ZooKeeper的目標就是封裝好複雜易出錯的關鍵服務,將簡單易用的介面和效能高效、功能穩定的系統提供給使用者
- ZooKeeper包含一個簡單的原語集,提供Java和C的介面。
簡單的說: 通過在zookeeper裡面註冊znode節點,可以做兩件事情
- 對於分散式服務來說,通過zookeeper可以作為管理節點的一個橋樑,就拿Hbase來說,當你增加一個regionserver的時候根本不需要去master那裡去增加一些配置,你只需要在regionserver上配置好zookeeper的地址,master隔幾秒會去zookeeper上看下,是否有多了regionserver,如果有就自動使用了,master,regionserver都在zookeeper上註冊著,所以jdbc連線也只要去zookeeper上查就可以知道該連哪個master
- 我們可以自動監控這些節點是否活著,而不用手動去實現這些事情,所以zookeeper解決了使用者想知道節點“是否活著?”的問題
快速開始
安裝
服務端,在每一臺需要監控的機器上安裝
yum install zookeeper-server
客戶端
yum install zookeeper-client
配置
編輯 /etc/zookeeper/conf/zoo.cfg ,所有機器上的 zoo.cfg 這個檔案都是一樣的maxClientCnxns=50 # The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. dataDir=/var/lib/zookeeper # the port at which the clients will connect clientPort=2181 server.1=host1:2888:3888 server.2=host2:2888:3888
- tickTime 單位是毫秒,被用作計算會話超時時間和心跳時間的最小單位,這兩個時間會被表示成 tickTime 的倍數,而不是直接寫上毫秒數,不懂這樣設計的好處在哪裡,不過至少使用者簡單了一點,只需要寫上倍數就行了
- dataDir 儲存記憶體資料的快照或者關於事務的更新日誌
- clientPort 給客戶端使用的埠
使用
在所有機器上啟動zookeeperservice zookeeper-server start
使用 zookeeper-client 進入客戶端
[zk: localhost:2181(CONNECTED) 0]
使用help命令看看有什麼可以用的命令
[zk: localhost:2181(CONNECTED) 0] help ZooKeeper -server host:port cmd args connect host:port get path [watch] ls path [watch] set path data [version] rmr path delquota [-n|-b] path quit printwatches on|off create [-s] [-e] path data acl stat path [watch] close ls2 path [watch] history listquota path setAcl path acl getAcl path sync path redo cmdno addauth scheme auth delete path [version] setquota -n|-b val path
我們來試試看最簡單的 ls 命令
[zk: localhost:2181(CONNECTED) 1] ls /
[hadoop-ha, hbase, zookeeper]
[zk: localhost:2181(CONNECTED) 2] ls /hadoop-ha
[mycluster]
可以看到下面有三個節點,hadoop-ha 下面還有一個節點。這都是因為我之前的教程已經安裝了hadoop和hbase所以會有這些節點。做到這裡,我們明白了,zookeeper維持了一個類似資料夾結構的空間,在這個空間記憶體儲的東西就是znode,znode可以有自己的子節點
建立節點
接下來,我們試試建立一個新的節點[zk: localhost:2181(CONNECTED) 3] create /zk_test my_data
Created /zk_test
[zk: localhost:2181(CONNECTED) 4] ls /
[hadoop-ha, hbase, zookeeper, zk_test]
這個zk_test 是我們要建立的節點名字,my_data 是節點的資料。 我們可以用get命令看下節點的資料
節點資料
[zk: localhost:2181(CONNECTED) 5] get /zk_test
my_data
cZxid = 0x2200000019
ctime = Sun Jan 18 02:30:56 PST 2015
mZxid = 0x2200000019
mtime = Sun Jan 18 02:30:56 PST 2015
pZxid = 0x2200000019
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0
在講解這些引數之前先介紹一下一個概念: ZooKeeper以多種方式跟蹤時間
- zxid:每次修改ZooKeeper狀態都會收到一個zxid形式的時間戳,也就是ZooKeeper事務ID。事務ID是ZooKeeper中所有修改總的次序。每個修改都有唯一的zxid,如果zxid1小於zxid2,那麼zxid1在zxid2之前發生。
- 版本號:對節點的每次修改將使得節點的版本號增加一。版本號有三種:version(znode資料修改的次數)、cversion(znode子節點修改的次數),以及aversion(znode的ACL修改次數)。
- tick:多伺服器ZooKeeper中,伺服器使用tick來定義狀態上傳、會話超時、節點間連線超時等事件的時序。tick僅被最小會話超時(2倍的tick時間)間接使用:如果客戶端要求小於最小會話超時的時間,伺服器將告知客戶端,實際使用的是最小會話超時。
- 真實時間:除了在建立和修改znode時將時間戳放入stat結構體中之外,ZooKeeper不使用真實時間,或者說時鐘時間。
- czxid:建立節點的事務的zxid
- mzxid:對znode最近修改的zxid
- ctime:以距離時間原點(epoch)的毫秒數表示的znode建立時間
- mtime:以距離時間原點(epoch)的毫秒數表示的znode最近修改時間
- pzxid:子節點的最後版本
- cversion:znode子節點修改次數
- dataVersion:資料的版本
- aclVersion:znode的ACL修改次數
- ephemeralOwner:如果znode是臨時節點,則指示節點所有者的會話ID;如果不是臨時節點,則為零。
- dataLength:znode資料長度。
- numChildren:znode子節點個數。
修改節點
不需要完全看懂以上這些引數,我們可以試著修改一下資料再看[zk: localhost:2181(CONNECTED) 6] set /zk_test junk
cZxid = 0x2200000019
ctime = Sun Jan 18 02:30:56 PST 2015
mZxid = 0x220000001a
mtime = Sun Jan 18 02:55:35 PST 2015
pZxid = 0x2200000019
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
[zk: localhost:2181(CONNECTED) 7] get /zk_test
junk
cZxid = 0x2200000019
ctime = Sun Jan 18 02:30:56 PST 2015
mZxid = 0x220000001a
mtime = Sun Jan 18 02:55:35 PST 2015
pZxid = 0x2200000019
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
再對比一下之前的引數,會發現以下引數改變了
- mZxid :變為另一個數據,表示最後修改的版本
- mtime:最後修改時間變了
- dataVersion:從0變成1,表示資料的版本增加了1
- dataLength:資料長度變化了
什麼是ACL
ZooKeeper使用ACL控制對節點的訪問。ACL的實現同Unix檔案訪問許可權非常相似:採用許可權位來定義允許/禁止的各種節點操作,以及位應用的範圍。與標準Unix許可權不同的是,ZooKeeper節點不由使用者(檔案所有者)、組和其他這三個標準範圍來限制。ZooKeeper沒有節點所有者的概念。取而代之的是,ACL指定一個ID集合,以及與這些ID相關聯的許可權。 還要注意的是,ACL僅僅用於某特定節點。特別是,ACL不會應用到子節點。比如說,/app只能被ip:172.16.16.1讀取,/app/status可以被所有使用者讀取。ACL不是遞迴的。ZooKeeper支援可插入式鑑權模式。使用scheme:id的形式指定ID,其中scheme是id對應的鑑權模式。比如說,ip:172.16.16.1是地址為172.16.16.1的主機的ID。 客戶端連線到ZooKeeper,驗證自身的時候,ZooKeeper將所有對應客戶端的ID都關聯到客戶端連線上。客戶端試圖存取節點的時候,ZooKeeper會在節點的ACL中校驗這些ID。ACL由(scheme:expression,perms)對組成。expression的格式是特定於scheme的。比如說,(ip:19.22.0.0/16,READ)給予任何IP地址以19.22開頭的客戶端以READ許可權。只需要知道概念就行了,具體的使用等需要的時候再學習。
刪除節點
[zk: localhost:2181(CONNECTED) 8] delete /zk_test
[zk: localhost:2181(CONNECTED) 9] ls /
[hadoop-ha, hbase, zookeeper]
可以看到節點被刪除了
總結
其實這個教程只是讓你知道了zookeeper是如何管理節點的,但是沒有說明zookeeper是如何監聽節點和標記節點的,因為那些有點複雜並且對我們普通開發者其實作用不太大,這些一般是 hadoop或者storm 的開發者需要考慮的問題。我們作為終端使用者只需要對zookeeper是個怎樣的東西,究竟是長什麼樣子有一個感性的認識就可以了。參考資料
- http://zookeeper.apache.org/doc/trunk/zookeeperStarted.html
- http://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#sc_zkDataModel_znodes
- http://blog.163.com/wm_at163/blog/static/132173490201232423051163/