[TOC]
1 zookeeper網(wǎng)站
以上是zookeeper的學(xué)習(xí)網(wǎng)站六水,可以先看中文快速了解基礎(chǔ)的概念,再看英文原版凰盔,從而保證理解上面經(jīng)量少的偏差
2 zookeeper的安裝和使用入門
2.1 zookeeper安裝與啟動(dòng)
1 安裝啟動(dòng)
在官方網(wǎng)站下載安裝包之后墓卦,解壓到喜歡的文件,在conf目錄下創(chuàng)建一個(gè)zoo.cfg 文件作為配置文件,內(nèi)容如下
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
tickTime: 在zookeeper體系中户敬,以毫秒的為單位的基礎(chǔ)時(shí)間單位值落剪。用作心跳檢測(cè)和session過期(兩倍的tickTime時(shí)間)
dataDir: 存儲(chǔ)目錄
clientPort: 客戶端連接時(shí)使用的端口
配置完成之后。執(zhí)行安裝目錄下bin目錄里面的 zkServer.sh
, 例如:/bin/zkServer.sh start
,啟動(dòng)服務(wù)
2 客戶端連接
執(zhí)行安裝目錄下的zkCli.sh 腳本使用命令行連接尿庐,bin/zkCli.sh -server 127.0.0.1:2181
連接進(jìn)入之后忠怖,使用help可以看到一些操作命令,例如
`ls /` 查看根目錄下面的節(jié)點(diǎn)
`create` 創(chuàng)建節(jié)點(diǎn)屁倔,例如 create /zk_test my_test_data ,在根目錄下創(chuàng)建zk_test
`set` 設(shè)置節(jié)點(diǎn)的值脑又,例如 set /zk_test my_new_test_data
`get` 獲取節(jié)點(diǎn)的值, 例如 get /zk_test
`delete` 刪除節(jié)點(diǎn)锐借,例如 delete /zk_testls
在zookeeper里面问麸,所有的節(jié)點(diǎn)都是一個(gè)路徑,例如在zk_test下面創(chuàng)建一個(gè)test節(jié)點(diǎn)钞翔,就需要知名路徑严卖,create /zk_test/test test_data,所有操作中path 參數(shù)從根目錄開始
2.2 zookeeper主從(replicated zookeeper)
主從模式配置和單點(diǎn)模式基本很相似,只是多加入了幾個(gè)配置
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: 設(shè)置參與的機(jī)器(quorum)連接到leader的超時(shí)時(shí)間布轿,單位為tickTime設(shè)置的時(shí)間哮笆,如上配置 這個(gè)時(shí)間=2000*5=10000ms=10s
syncLimit: 設(shè)置從機(jī)器到leader的延時(shí)時(shí)間上限
server.x 代表服務(wù)器的,其中有一個(gè)是master汰扭,建議最少使用三臺(tái)以上服務(wù)稠肘,zookeeper和redis有點(diǎn)像,使用選舉的策略萝毛,所以项阴,最好是奇數(shù)的服務(wù)器數(shù)量。 server name后面的兩個(gè)端口笆包,前面的端口用來連接follower和leader环揽,當(dāng)新的leader選出來之后,follower就通過這個(gè)端口和leader建立連接庵佣。后面的端口是作為leader選舉時(shí)候的端口
3 zookeeper
了解zookeeper的時(shí)候歉胶,四個(gè)最重要的元素一定要知道 ,數(shù)據(jù)結(jié)構(gòu)(node/Sate)巴粪,Session, Watcher, ACL通今,從這開始粥谬,依次來了解這些東西
3.1 zookeeper的數(shù)據(jù)結(jié)構(gòu)
zookeeper是一個(gè)分成的命名空間(hierarchal name space) ,非常像一個(gè)分布式文件系統(tǒng)。命令空間的每個(gè)節(jié)點(diǎn)可以有自己的數(shù)據(jù)和子節(jié)點(diǎn)辫塌。zookeeper的子節(jié)點(diǎn)稱之為znode,znode維護(hù)了一個(gè)stat的數(shù)據(jù)結(jié)構(gòu)
3.1.1 zookeeper計(jì)時(shí)
Zookeeper通過多種方式追蹤計(jì)時(shí):
Zxid
每個(gè)Zookeeper狀態(tài)的變化都以zxid(事務(wù)ID)的形式接收到標(biāo)記帝嗡。這個(gè)暴露了Zookeeper所有變化的總排序。每個(gè)變化都會(huì)有一個(gè)zxid璃氢,并且如果zxid1早于zxid2則zxid1一定小于zxid2哟玷。
版本號(hào)
節(jié)點(diǎn)的每個(gè)變化都會(huì)引起那個(gè)節(jié)點(diǎn)的版本號(hào)的其中之一增加。這三個(gè)版本號(hào)是version(znode的數(shù)據(jù)變化版本號(hào)),cversion(子目錄的變化版本號(hào))一也,和aversion(訪問控制列表的變化版本號(hào))巢寡。
Ticks
當(dāng)使用多服務(wù)器的Zookeeper時(shí),服務(wù)器使用ticks定義事件的時(shí)間椰苟,如狀態(tài)上傳抑月,會(huì)話超時(shí),同事之間的連接超時(shí)等等舆蝴。tick次數(shù)只是通過最小的會(huì)話超時(shí)間接的暴露谦絮;如果一個(gè)客戶端請(qǐng)求會(huì)話超時(shí)小于最小的會(huì)話超時(shí),服務(wù)器就會(huì)告訴客戶端會(huì)話超時(shí)實(shí)際上是最低會(huì)話超時(shí)時(shí)間洁仗。
Real time
Zookeeper不使用實(shí)時(shí)或時(shí)鐘時(shí)間层皱,除了將時(shí)間戳加在znode創(chuàng)建和更新的stat結(jié)構(gòu)上。
3.1.2 stat數(shù)據(jù)結(jié)構(gòu)
執(zhí)行 get命令查看一個(gè)節(jié)點(diǎn)的時(shí)候就可以看到赠潦,例如 get /zk_test
my_test_data
cZxid = 0x8
ctime = Fri Jun 23 11:05:38 CST 2017
mZxid = 0x8
mtime = Fri Jun 23 11:05:38 CST 2017
pZxid = 0xa
cversion = 2
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 12
numChildren = 0
my_test_data 使我們存放的數(shù)據(jù)
3.2 zookeeper session
主要是控制會(huì)話狀態(tài)
下面是官網(wǎng)提供的狀態(tài)轉(zhuǎn)換圖:
3.3 zookeeper watcher(重點(diǎn))
3.3.1 什么事watcher
zookeeper的讀操作叫胖,- getData(), getChildren(), and exists() ,都可以設(shè)置watcher. zookeeper中關(guān)于watch的定義是: 當(dāng)設(shè)置了watch的節(jié)點(diǎn)的數(shù)據(jù)發(fā)生了變化的時(shí)候她奥,會(huì)向客戶端發(fā)送一次(one-time trigger)watch的事件瓮增。(a watch event is one-time trigger, sent to the client that set the watch, which occurs when the data for which the watch was set changes)。
針對(duì)這個(gè)定義哩俭,有下面三個(gè)方面的結(jié)論:
- 一次觸發(fā):當(dāng)數(shù)據(jù)有了變化時(shí)將向客戶端發(fā)送一個(gè)watch事件绷跑。例如,如果一個(gè)客戶端用getData("/znode1",true)并且過一會(huì)之后/znode1的數(shù)據(jù)改變或刪除了凡资,客戶端將獲得一個(gè)/znode1的watch事件砸捏。如果/znode1再次改變,將不會(huì)發(fā)送watch事件除非設(shè)置了新watch讳苦。
- 發(fā)往客戶端: 這意味著事件發(fā)往客戶端带膜,但是可能在成功之前沒到客戶端吩谦。Watches是異步發(fā)往watchers鸳谜。Zookeeper提供一個(gè)順序保證:在看到watch事件之前絕不會(huì)看到變化。網(wǎng)絡(luò)延遲或其他因素可能引起客戶端看到watches并在不同時(shí)間返回code式廷。關(guān)鍵點(diǎn)是不同客戶端看到的是一致性的順序咐扭。
- 為數(shù)據(jù)設(shè)置watch: 一個(gè)節(jié)點(diǎn)可以有不同方式改變。它幫助Zookeeper維護(hù)兩個(gè)watches:data watches和child watches。getData()和exists()設(shè)置data watches蝗肪。getChildren()設(shè)置child watches袜爪。兩者任選其一,它可以幫助watches根據(jù)類型返回薛闪。getData()和exists()返回關(guān)于節(jié)點(diǎn)數(shù)據(jù)的信息辛馆,然而getChildren()返回children列表。因此豁延,setData()將會(huì)觸發(fā)znode設(shè)置的data watches昙篙。一個(gè)成功的create()將會(huì)觸發(fā)一個(gè)datawatches和一個(gè)父節(jié)點(diǎn)的child watch。一個(gè)成功的delete()將觸發(fā)一個(gè)data watch和一個(gè)child watch
watch事件類型列表及其觸發(fā)方法
- Created event:
Enabled with a call to exists. - Deleted event:
Enabled with a call to exists, getData, and getChildren. - Changed event:
Enabled with a call to exists and getData. - Child event:
Enabled with a call to getChildren.
3.3.2 watch作用
zookeeper設(shè)置了watch,只要作用是什么呢
- Watches和其他事件诱咏、watches和異步恢復(fù)都是有序的苔可。Zookeeper客戶端保證每件事都是有序派發(fā)
- 當(dāng)添加的watch的節(jié)點(diǎn)改變的了數(shù)據(jù)的時(shí)候,客戶端會(huì)先看到watch事件袋狞,之后才看到新數(shù)據(jù)
- watch事件的順序是和服務(wù)的數(shù)據(jù)改變的順序是一致的
3.4 zookeeper ACL訪問控制
acl主要是對(duì)zookeeper的node做訪問權(quán)限的控制焚辅,但是,這個(gè)訪問權(quán)限是不遞歸到子元素的苟鸯,也就是說同蜻,給node /test_node 設(shè)置的權(quán)限只會(huì)影響 /test_node ,不會(huì)影響他的子節(jié)點(diǎn)早处。
ACLs由對(duì)組成(scheme:expression,permissions)埃仪。expression的格式是針對(duì)scheme。
3.4.1 ACL 默認(rèn)的權(quán)限如下:
- CREATE: you can create a child node (可以創(chuàng)建 子節(jié)點(diǎn))
- READ: you can get data from a node and list its children.(可以查看節(jié)點(diǎn)數(shù)據(jù)和列出他的子節(jié)點(diǎn))
- WRITE: you can set data for a node (可以向節(jié)點(diǎn)設(shè)置數(shù)據(jù))
- DELETE: you can delete a child node (可以刪除 子節(jié)點(diǎn))
- ADMIN: you can set permissions (可以設(shè)置節(jié)點(diǎn)的權(quán)限)
在命令行創(chuàng)建的時(shí)候陕赃,直接使用cdrwa分別代表 create,delete,read,write,admin權(quán)限
3.4.2 ACL 內(nèi)置的scheme
Zookeeper有下面的schemes:
world:有單獨(dú)的id卵蛉,anyone,代表任何人, 例如節(jié)點(diǎn)得默認(rèn)權(quán)限 world:anyone:cdrwa
auth:不適用任何id,代表任何授權(quán)的用戶么库。
digest:使用username;password字符串生成MD5哈希作為ACL ID身份傻丝。通過發(fā)送username:password明文授權(quán)。在ACL里使用時(shí)expression將會(huì)是username:base64編碼的SHA1 password摘要诉儒。
ip:使用客戶端IP作為ACL ID身份葡缰。
設(shè)置權(quán)限之后,要想訪問忱反,就要獲得具體權(quán)限泛释。
示例:
- 命令行執(zhí)行就會(huì)創(chuàng)建一個(gè)節(jié)點(diǎn) /test_node 需要的用戶名密碼(fun:123123)登錄
create /test_node test_acl_data auth:fun:123123:cdrwa
- 查看權(quán)限 getAcl
[zk: 127.0.0.1:2181(CONNECTED) 5] getAcl /test_node
'digest,'fun:lpYnLtsL5UprZTlY9EGtvYhMZU0=
: cdrwa
上面執(zhí)行效果發(fā)現(xiàn),auth 帶上id(fun:123123)的時(shí)候温算,會(huì)得到效果就是digest的權(quán)限設(shè)置scheme,在沒有密碼的情況下執(zhí)行例如 get 會(huì)提示權(quán)限不夠
- 授權(quán)之后怜校,操作node
使用 addauth 方式授權(quán)
addauth digest fun:123123
之后操作就沒有問題了
關(guān)于zookeeper的ACL的總結(jié):
- acl的權(quán)限設(shè)置是對(duì)設(shè)置的節(jié)點(diǎn)有作用,對(duì)子節(jié)點(diǎn)沒有遞歸作用效果
- 授權(quán)和scheme有關(guān)系注竿,用什么scheme授權(quán)茄茁,添加授權(quán)(addauth)就用什么scheme
- addauth授權(quán)的生命周期同session周期一致