Zookeeper(1)-概述
?
目錄
ZooKeeper:分布式應用程序的分布式協調服務
1. 安裝
2. 使用
3. 構建zookeeper集群
4. paxos
5. ZAB?協議
5.1 ZAB選主
6. watch機制
6.1 特征
6.2 watch的使用方式
6.3?持久的、遞歸的手表
6.4? watch事件分類
創建節點
7.?ZooKeeper 會話
ZooKeeper:分布式應用程序的分布式協調服務
ZooKeeper 是分布式應用程序的分布式開源協調服務。它公開了一組簡單的原語,分布式應用程序可以基于這些原語來實現更高級別的同步、配置維護以及組和命名服務。它被設計為易于編程,并使用以熟悉的文件系統目錄樹結構為樣式的數據模型。它在 Java 中運行,并且具有 Java 和 C 的綁定。
1. 安裝
官網https://zookeeper.apache.org/
下載:https://zookeeper.apache.org/releases.html?
zookeeper運行需要jvm環境,所有需要提前安裝jdk
2. 使用
windows環境,
zkServer.cmd 服務端啟動,zkCli.cmd 客戶端連接
linux環境,
zkServer.sh 服務端啟動,zkCli.sh客戶端連接
連接客戶端進行簡單的命令操作。
https://zookeeper.apache.org/doc/current/zookeeperCLI.html?使用指南。
- ? ? ? ? addauth scheme auth?添加超級用戶
addauth scheme zookeeper:admin
?
- ? ? ? ? close?關閉此客戶端/會話
- ? ? ? ? config [-c] [-w] [-s] 顯示仲裁成員的配置
- ? ? ? ? connect host:port??連接 ZooKeeper 服務器
- ? ? ? ? create [-s] [-e] [-c] [-t ttl] path [data] [acl]? 創建目錄和數據?
create ?path data 持久,znode被創建后,創建其的client連接斷開或者zookeeper服務重啟,該節點都會依然存在?persistent_node
create -e path data 臨時,當創建改znode的client與zookeeper的連接斷開時,znode會被自動刪除,臨時模式znode不能有child node。執行quit后 。ephemeral_node?
create -s path data 序列,znode被創建后,znode名稱會自動添加一個編號,編號會自動遞增。?persistent_sequential_node?
create -e -s path data臨時+序列?和臨時(ephemeral)模式一樣,在創建znode的client和zookeeper斷開連接后,znode被自動刪除,創建時名稱會自動添加編號,編號會自動遞增?ephemeral_sequential_node?
create -t?? 3000 /ttl_node data 創建一個過期時間的node,3秒后消失
?
- ? ? ? ? delete [-v version] path 刪除指定目錄下節點
- ? ? ? ? deleteall path [-b batch size] 刪除/path下所有節點
- ? ? ? ? delquota [-n|-b] path??刪除路徑下的配額
- ? ? ? ? get [-s] [-w] path 獲取指定目錄下的數據
get /path
?get -w /path?-w 設置監視數據更改,注意:打開打印監視
[zkshell: 12] get -w /latest_producer_id_block {"version":1,"broker":0,"block_start":"0","block_end":"999"} [zkshell: 13] set /latest_producer_id_block mydata WATCHER: : WatchedEvent state:SyncConnected type:NodeDataChanged path:/latest_producer_id_block ```
get -s /path?顯示統計信息
cZxid :創建節點的id? ? ? ? 0紀元第4次操作
ctime : 節點的創建時間?
mZxid :修改節點的id? ? ? 0紀元第4次操作
mtime :修改節點的時間?
pZxid :子節點的id
cversion : 子節點的版本
dataVersion : 當前節點數據的版本
aclVersion :權限的版本
ephemeralOwner :判斷是否是臨時節點
dataLength : 數據的長度
numChildren :子節點的數量
?
- ? ? ? ? getAcl [-s] path?獲取一條路徑的ACL權限
bash [zkshell: 4] create /acl_test mydata ip:127.0.0.1:crwda Created /acl_test [zkshell: 5] getAcl /acl_test 'ip,'127.0.0.1 : cdrwa [zkshell: 6] getAcl /testwatch 'world,'anyone : cdrwa
?
?
- ? ? ? ? getAllChildrenNumber path?獲取特定路徑下的所有子節點數
- ? ? ? ? getEphemerals path?獲取此會話創建的所有臨時節點
- ? ? ? ? history?顯示有關您最近執行的 11 個命令的歷史記錄
- ? ? ? ? listquota path?列出一條路徑的配額
- ? ? ? ? ls [-s] [-w] [-R] path??列出一條路徑的子節點
-s 顯示統計信息
-R 遞歸顯示子節點
-w 設置監視孩子的變化,注意:打開打印手表,當刪除node是,會監控到
[zkshell: 39] ls -w /brokers [ids, seqid, topics] [zkshell: 40] 刪除/brokers/ids WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/brokers ```
?
- ? ? ? ? printwatches on|off??無論是否打印watch,都可以打開/關閉開關
?
?
- ? ? ? ? quit 退出
- ? ? ? ? reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*] 重新配置
將follower 2更改為觀察者并將其端口從2182更改為12182
將觀察者 5 添加到集合中
從整體中移除觀察者 4
[zkshell: 1] reconfig --add 2=localhost:2781:2786:observer;12182 --add 5=localhost:2781:2786:observer;2185 -remove 4 提交新配置:server.1=localhost:2780:2785 :participant;0.0.0.0:2181 server.2=localhost:2781:2786:observer;0.0.0.0:12182 server.3=localhost:2782:2787:participant;0.0.0.0:2183 server.5=localhost:2784: 2789:觀察者;0.0.0.0:2185 版本=1c00000002
?
- ? ? ? ? redo cmdno
使用歷史記錄中的索引重做 cmd。
先用history命令展示,用redo 命令執行
history 0 - ls / 1 - get /consumers 2 - get /hbase 3 - ls /hbase 4 - history [zkshell: 5] redo 3?
?
- ? ? ? ? removewatches path [-c|-d|-a] [-l]? ?刪除節點下的手表。
?
- ? ? ? ? set [-s] [-v version] path data 設置/更新路徑上的數據。
? -s?顯示此節點的狀態?set -s /hello aaa
-v 使用 CAS 設置數據,可以使用 stat 從 dataVersion 中找到版本。set -v 4 /hello aaa
- ? ? ? ?- setAcl [-s] [-v version] [R] path acl?為一個節點設置 Acl 權限? setAcl /hello auth:user1:12345:crwad
ACL 權限控制,使用:scheme:id:perm?來標識,主要涵蓋 3 個方面:
權限模式(Scheme):授權的策略
授權對象(ID):授權的對象
權限(Permission):授予的權限
1.? scheme? 采用何種方式授權
world:默認方式,相當于全部都能訪問 setAcl /hello? world world:anyone:crwda
auth:代表已經認證通過的用戶(cli中可以通過addauth digest user:pwd 來添加當前上下文中的授權用戶) ,需要先添加auth ,addauth digest user:pwd, 然后 setAcl /hello world auth:user:pwd:crwda
digest:即用戶名:密碼這種方式認證,這也是業務系統中最常用的。用?username:password?字符串來產生一個MD5串,然后該串被用來作為ACL ID。認證是通過明文發送username:password?來進行的,當用在ACL時,表達式為username:base64?,base64是password的SHA1摘要的編碼。?digest:username:BASE64(SHA1(password)):cdrwa
ip:使用客戶端的主機IP作為ACL ID 。這個ACL表達式的格式為addr/bits?,此時addr中的有效位與客戶端addr中的有效位進行比對。setAcl /hello world ip:127.0.0.1:crwda?節點只允許IP為127.0.0.1的客戶端能讀寫該寫節點的數據
2.? ID???給誰授予權限
id是驗證模式,不同的scheme,id的值也不一樣。
scheme為digest時,id的值為:username:BASE64(SHA1(password)),
scheme為ip時,id的值為客戶端的ip地址。
scheme為world時,id的值為anyone。
scheme為auth時,id為 username:password。
授權對象ID是指,權限賦予的用戶或者一個實體,例如:IP 地址或者機器。授權模式 schema 與 授權對象 ID 之間
3.? permission? ?授予什么權限
CREATE、READ、WRITE、DELETE、ADMIN?也就是?增、刪、改、查、管理權限,這5種權限簡寫為crwda
注意:
這5種權限中,delete是指對子節點的刪除權限,其它4種權限指對自身節點的操作權限
更詳細的如下:
CREATE? ?c 可以創建子節點
DELETE? ?d 可以刪除子節點(僅下一級節點)
READ? ? ? ?r 可以讀取節點數據及顯示子節點列表
WRITE? ? ?w 可以設置節點數據
ADMIN? ? ?a 可以設置節點訪問控制列表權限
- ? ? ? ? setquota -n|-b val path?在一個路徑中設置配額
?限制子節點的數量(包括本身)
setquota -n 2 /quota_test?
-b 限制一條路徑的字節數(數據長度)
?setquota -b 5 /brokers
- ? ? ? ? stat [-w] path?顯示一個節點的統計/元數據。
- ? ? ? ? sync path?
在leader和follower之間同步一個節點的數據(異步同步)sync /
- ? ? ? ? version 版本
3. 構建zookeeper集群
為了獲得可靠的 ZooKeeper 服務,您應該將 ZooKeeper 部署在一個稱為ensemble的集群中。只要大多數合奏都已啟動,該服務就可用。因為 Zookeeper 需要多數,所以最好使用奇數臺機器。比如有四臺機器的ZooKeeper只能處理一臺機器的故障;如果兩臺機器出現故障,剩下的兩臺機器不構成多數。然而,有了五臺機器,ZooKeeper 可以處理兩臺機器的故障。
server.x=[hostname]:nnnnn[:nnnnn] 等:(無 Java 系統屬性)組成 ZooKeeper 集合的服務器。當服務器啟動時,它通過在數據目錄中查找文件myid來確定它是哪個服務器。該文件包含了服務器數量,在ASCII,它應該與X在server.x在此設置的左側。客戶端使用的組成 ZooKeeper 服務器的服務器列表必須與每個 ZooKeeper 服務器擁有的 ZooKeeper 服務器列表相匹配。
有兩個端口號nnnnn。第一個follower用于連接leader,第二個用于leader選舉。如果你想在一臺機器上測試多臺服務器,那么每臺服務器可以使用不同的端口。
從 ZooKeeper 3.6.0 開始,可以為每個 ZooKeeper 服務器指定多個地址(參見ZOOKEEPER-3188)。要啟用此功能,您必須將multiAddress.enabled配置屬性設置為true。這有助于提高可用性并為 ZooKeeper 添加網絡級別的彈性。當服務器使用多個物理網絡接口時,ZooKeeper 能夠綁定所有接口,并在網絡錯誤的情況下運行時切換到工作接口。可以使用管道 ('|') 字符在配置中指定不同的地址。使用多個地址的有效配置如下所示:
server.1=zoo1-net1:2888:3888|zoo1-net2:2889:3889 server.2=zoo2-net1:2888:3888|zoo2-net2:2889:3889 server.3=zoo3-net1:2888:3888|zoo3-net2:2889:3889windows下集群
1. 配置conf
復制4個cfg文件,其實3個就夠,強烈推薦基數臺。這里我是配置了4個,這個不重要。如果想在同一臺機器上進行模擬,由于ip都是localhost,所以建議修改端口號。如果是在不同的機器上,由于ip不同,端口號可以相同。反正注意一下這個事。
2. 復制4個啟動腳本
在啟動腳本中指定一下啟動時需要的配置。
3. 根據cfg中配置的dataDir、dataLogDir兩個地址去創建目錄
并且需要再dataDir目錄下創建一個myid的文件,每個服務對應一個dataDir目錄,將節點編號配置到myid文件中。
4. paxos
這里可能一下在不太懂,可以先繼續往下學習,返回來在看這個,就明白了
先說Paxos,它是一個基于消息傳遞的一致性算法,Leslie Lamport在1990年提出,近幾年被廣泛應用于分布式計算中,Google的Chubby,Apache的Zookeeper都是基于它的理論來實現的,Paxos還被認為是到目前為止唯一的分布式一致性算法,其它的算法都是Paxos的改進或簡化。有個問題要提一下,Paxos有一個前提:沒有拜占庭將軍問題。就是說Paxos只有在一個可信的計算環境中才能成立,這個環境是不會被入侵所破壞的。
關于Paxos的具體描述可以在Wiki中找到:http://zh.wikipedia.org/zh-cn/Paxos算法。網上關于Paxos分析的文章也很多。這里希望用最簡單的方式加以描述并建立起Paxos和ZK Server的對應關系。
Paxos描述了這樣一個場景,有一個叫做Paxos的小島(Island)上面住了一批居民,島上面所有的事情由一些特殊的人決定,他們叫做議員(Senator)。議員的總數(Senator Count)是確定的,不能更改。島上每次環境事務的變更都需要通過一個提議(Proposal),每個提議都有一個編號(PID),這個編號是一直增長的,不能倒退。每個提議都需要超過半數((Senator Count)/2 +1)的議員同意才能生效。每個議員只會同意大于當前編號的提議,包括已生效的和未生效的。如果議員收到小于等于當前編號的提議,他會拒絕,并告知對方:你的提議已經有人提過了。這里的當前編號是每個議員在自己記事本上面記錄的編號,他不斷更新這個編號。整個議會不能保證所有議員記事本上的編號總是相同的。現在議會有一個目標:保證所有的議員對于提議都能達成一致的看法。
好,現在議會開始運作,所有議員一開始記事本上面記錄的編號都是0。有一個議員發了一個提議:將電費設定為1元/度。他首先看了一下記事本,嗯,當前提議編號是0,那么我的這個提議的編號就是1,于是他給所有議員發消息:1號提議,設定電費1元/度。其他議員收到消息以后查了一下記事本,哦,當前提議編號是0,這個提議可接受,于是他記錄下這個提議并回復:我接受你的1號提議,同時他在記事本上記錄:當前提議編號為1。發起提議的議員收到了超過半數的回復,立即給所有人發通知:1號提議生效!收到的議員會修改他的記事本,將1好提議由記錄改成正式的法令,當有人問他電費為多少時,他會查看法令并告訴對方:1元/度。
現在看沖突的解決:假設總共有三個議員S1-S3,S1和S2同時發起了一個提議:1號提議,設定電費。S1想設為1元/度, S2想設為2元/度。結果S3先收到了S1的提議,于是他做了和前面同樣的操作。緊接著他又收到了S2的提議,結果他一查記事本,咦,這個提議的編號小于等于我的當前編號1,于是他拒絕了這個提議:對不起,這個提議先前提過了。于是S2的提議被拒絕,S1正式發布了提議: 1號提議生效。S2向S1或者S3打聽并更新了1號法令的內容,然后他可以選擇繼續發起2號提議。
好,我覺得Paxos的精華就這么多內容。現在讓我們來對號入座,看看在ZK Server里面Paxos是如何得以貫徹實施的。
小島(Island)——ZK Server Cluster
議員(Senator)——ZK Server
提議(Proposal)——ZNode Change(Create/Delete/SetData…)
提議編號(PID)——Zxid(ZooKeeper Transaction Id)
正式法令——所有ZNode及其數據
貌似關鍵的概念都能一一對應上,但是等一下,Paxos島上的議員應該是人人平等的吧,而ZK Server好像有一個Leader的概念。沒錯,其實Leader的概念也應該屬于Paxos范疇的。如果議員人人平等,在某種情況下會由于提議的沖突而產生一個“活鎖”(所謂活鎖我的理解是大家都沒有死,都在動,但是一直解決不了沖突問題)。Paxos的作者Lamport在他的文章”The Part-Time Parliament“中闡述了這個問題并給出了解決方案——在所有議員中設立一個總統,只有總統有權發出提議,如果議員有自己的提議,必須發給總統并由總統來提出。好,我們又多了一個角色:總統。
總統——ZK Server Leader
又一個問題產生了,總統怎么選出來的?oh, my god! It’s a long story. 在淘寶核心系統團隊的Blog上面有一篇文章是介紹如何選出總統的,有興趣的可以去看看:http://rdc.taobao.com/blog/cs/?p=162
現在我們假設總統已經選好了,下面看看ZK Server是怎么實施的。
情況一:
屁民甲(Client)到某個議員(ZK Server)那里詢問(Get)某條法令的情況(ZNode的數據),議員毫不猶豫的拿出他的記事本(local storage),查閱法令并告訴他結果,同時聲明:我的數據不一定是最新的。你想要最新的數據?沒問題,等著,等我找總統Sync一下再告訴你。
情況二:
屁民乙(Client)到某個議員(ZK Server)那里要求政府歸還欠他的一萬元錢,議員讓他在辦公室等著,自己將問題反映給了總統,總統詢問所有議員的意見,多數議員表示欠屁民的錢一定要還,于是總統發表聲明,從國庫中拿出一萬元還債,國庫總資產由100萬變成99萬。屁民乙拿到錢回去了(Client函數返回)。
情況三:
總統突然掛了,議員接二連三的發現聯系不上總統,于是各自發表聲明,推選新的總統,總統大選期間政府停業,拒絕屁民的請求。
呵呵,到此為止吧,當然還有很多其他的情況,但這些情況總是能在Paxos的算法中找到原型并加以解決。這也正是我們認為Paxos是Zookeeper的靈魂的原因。當然ZK Server還有很多屬于自己特性的東西:Session, Watcher,Version等等等等,需要我們花更多的時間去研究和學習。
?
?
?
5. ZAB?協議
ZAP? ,z是zookeeper ,a是 原子性, b是廣播性
ZAB 協議是為分布式協調服務ZooKeeper專門設計的一種支持崩潰恢復的一致性協議。基于該協議,ZooKeeper 實現了一種主從模式的系統架構來保持集群中各個副本之間的數據一致性。
原子:只有成功和是失敗,沒有中間狀態
廣播:分布式多節點,進行兩兩通信,將自己能的節點信息廣播給其他節點。(過半,最終一致性)
5.1 ZAB選主
選主依據:
1. election epoch, Zxid中的紀元(epoch),誰新優先選誰
2. zxid? Zxid的事務編號,誰新優先選誰。誰的Zxid編號越大,表示版本最新,數據最新
3. myid 節點編號,誰新優先選誰
?
選主過程
場景一,首次啟動的時候
,首次啟動的時候,Zxid都為0,所以會按照sid選主。
假設
A 節點,sid1
B 節點,sid=2
C節點,sid=3
D節點,sid=4
這種情況,由于是4個節點,需要(4/2)+1個節點同一,三個節點就可以選出leader
所以需要看啟動順序,如果先啟動A B C,最后啟動D,則C是leader
如果先啟動A B D,最后啟動C,則D是leader
?
場景二,leader掛掉,follower選主
如果原先D節點為leader,結果D掛掉了。由其他三個節點選取leader。過半的話,需要三臺都同意
A發起投票
B發起投票
C發起投票
結論:最終3個節點都選擇了C,并且每個節點都知道其他節點的選擇。,過半的節點選擇了C節點,所以C就是新leader
6. watch機制
6.1 特征
?ZooKeeper 中的所有讀取操作 -?getData()、getChildren()和exists()?- 都可以選擇將監視設置為副作用。以下是 ZooKeeper 對 watch 的定義:watch 事件是一次性觸發器,發送到設置 watch 的客戶端,當設置 watch 的數據發生變化時發生。在對手表的定義中,需要考慮三個關鍵點:
-
一次性觸發 ,watcher是一次性的,就是說當觸發了watcher事件后,這個watcher就不存在了,下次變更就不會再次觸發watcher事件。所以需要重新注冊watcher,
3.6.0 中的新功能:客戶端還可以在 znode 上設置永久的遞歸監??視,這些監視在觸發時不會被刪除,并且會以遞歸方式觸發注冊的 znode 以及任何子 znode 上的更改。
?
-
發送到客戶端,意思是,第一次修改數據觸發watcher事件,當事件正在返回客戶端,第二次數據修改也觸發了這個事件,這種情況,zk中會維護一個隊列,能夠保證這些變更產生的watcher事件有序的返回到客戶端。
-
watcher設置的數據這是指節點可以改變的不同方式。將 ZooKeeper 視為維護兩個監視列表會有所幫助:數據監視和子監視。
-
getData() 和 exists() 設置數據監視。
-
getChildren() 設置子手表。或者,考慮根據返回的數據類型設置手表可能會有所幫助。getData() 和 exists() 返回有關節點數據的信息,而 getChildren() 返回子節點列表。因此, setData() 將觸發正在設置的 znode 的數據監視(假設設置成功)。成功的 create() 將觸發正在創建的 znode 的數據觀察和父 znode 的子觀察。成功的 delete() 將同時觸發數據觀察和子觀察(因為不能再有子節點)被刪除的 znode 以及父 znode 的子觀察。
Watches 在客戶端連接到的 ZooKeeper 服務器上本地維護。這允許手表在設置、維護和調度方面是輕量級的。當客戶端連接到新服務器時,任何會話事件都會觸發監視。與服務器斷開連接時將不會收到手表。當客戶端重新連接時,如果需要,任何先前注冊的手表將被重新注冊和觸發。一般來說,這一切都是透明的。有一種情況可能會丟失監視:如果在斷開連接時創建和刪除 znode,則會丟失尚未創建的 znode 存在的監視。
6.2 watch的使用方式
我們可以使用三個讀取 ZooKeeper 狀態的調用來設置監視:exists、getData 和 getChildren。以下列表詳細說明了監視可以觸發的事件以及啟用它們的調用:
- Created 事件:通過調用exists 啟用。
- Deleted 事件:通過調用exists、getData 和getChildren 啟用。
- set事件:通過調用exists 和getData 啟用。
- children事件:通過調用 getChildren 啟用。
6.3?持久的、遞歸的手表
標準手表是一次性觸發器;如果您收到一個 watch 事件,并且希望收到有關未來更改的通知,則必須設置另一個 watch。
但是,因為標準手表是一次性觸發器,并且在獲取事件和發送新請求以獲取手表之間存在延遲,所以您無法可靠地看到 ZooKeeper 中節點發生的每一個變化。準備好處理 znode 在獲取事件和再次設置 watch 之間多次更改的情況。
舉個例子:在觸發了第一次watcher,調用process方法,此時watcher已經不存在了,是一次性的,但是,在重新設置watcher之前,該路徑/myHello02 有發生變化,此時正處于第一個watcher失效,新watcher沒有設置之前,這種情況就無法監控了。可能這個有個容忍性,但是需要注意這個點
標準watch:
設置一個標準watcher
1. 創建path? ?/aaaa
2. 通過get 設置 標準watcher
3. 修改數據為 bbbb
此時會觸發watcher事件
4. 再次修改數據為 cccc,此時不能夠觸發事件,標準watcher是一次性的。
5. 重新設置watcher?
6. 再次修改數據dddd,還是可以觸發事件的。但是在重新設置之前如果有其他的客戶操作了/aaaa, 則不會被監控到
?
所以,3.6.0 中的新功能:現在在上述標準手表上有一個變體,您可以設置一個在觸發時不會被移除的手表。此外,這些監視會觸發事件類型NodeCreated、NodeDeleted和NodeDataChanged ,并且可以選擇遞歸地針對所有從監視注冊的 znode 開始的 znode。
使用addWatch方法設置持久監視。觸發語義和保證(一次性觸發除外)與標準手表相同。兩種模式:永久? 永久_遞歸
?addWatch [-m mode] path # optional mode is one of [PERSISTENT, PERSISTENT_RECURSIVE] - default is PERSISTENT_RECURSIVE
add watch /a 默認為一個持久遞歸類型、? add -m?PERSISTENT/a 僅持久
NodeCreated、NodeDeleted和NodeDataChanged 都會觸發事件。
?
?
可以使用removewath來刪這個持久監控watcher
區別:兩種持久化watch的區別:
PERSISTENT, 操作和標準watch一致。只是持久化,就是觸發后不會被刪除。
PERSISTENT_RECURSIVE,若客戶端設置了PERSISTENT_RECURSIVE模式的Watch,那么所有節點都會進行遞歸操作,而該watch會被觸發事件的只有當被綁定的節點的內容被更新或其子節點的創建、刪除、內容更新。【但NodeChildrenChanged事件不會觸發到該watch】;
6.4? watch事件分類
-
創建節點
觸發當前節點的NodeCreated事件
觸發當前節點的父節點的NodeChildrenChanged事件
-
刪除節點
觸發當前節點的NodeDeleted事件
觸發當前節點的父節點的NodeChildrenChanged事件
-
修改節點
觸發當前節點的NodeDataChanged事件
7.?ZooKeeper 會話
ZooKeeper 客戶端通過使用語言綁定創建服務句柄來建立與 ZooKeeper 服務的會話。
狀態:stat
創建后,句柄以 CONNECTING 狀態開始,客戶端庫嘗試連接到構成 ZooKeeper 服務的服務器之一,此時它切換到 CONNECTED 狀態,在正常操作期間,客戶端句柄將處于這兩種狀態之一。
如果發生不可恢復的錯誤,例如會話過期或身份驗證失敗,或者如果應用程序明確關閉句柄,則句柄將移動到 CLOSED 狀態。
?
創建會話需要的要素:
1. 包含逗號分隔的主機:端口對列表的連接字符串,每個對應于一個 ZooKeeper 服務器(例如“127.0.0.1:4545”或“127.0.0.1:3000,127.0.0.1 :3001,127.0.0.1:3002")
在 3.2.0 中添加:可選的“chroot”后綴也可以附加到連接字符串127.0.0.1:4545/app/a”或“127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a。這樣相當于將/app/a當做根目錄。場景用途:例如,一個Zookeeper集群被多個系統使用,不同系統可以建立不同系統的目錄。
當客戶端獲得 ZooKeeper 服務的句柄時,ZooKeeper 會創建一個 ZooKeeper 會話,表示為一個 64 位數字,并將其分配給客戶端。如果客戶端連接到不同的 ZooKeeper 服務器,它將發送會話 ID 作為連接握手的一部分。作為一種安全措施,服務器為 session id 創建一個密碼,任何 ZooKeeper 服務器都可以驗證該密碼。當客戶端建立會話時,密碼將與 session id 一起發送到客戶端。每當客戶端與新服務器重新建立會話時,客戶端都會發送帶有會話 ID 的密碼。
2. 會話超時時間:用于創建 ZooKeeper 會話的 ZooKeeper 客戶端庫調用的參數之一是以毫秒為單位的會話超時。客戶端發送請求的超時,服務器以它可以給客戶端的超時響應。當前的實現要求超時時間至少是tickTime 的2 倍(在服務器配置中設置),最大是tickTime 的20 倍。ZooKeeper 客戶端 API 允許訪問協商超時
當客戶端(會話)從 ZK 服務集群分區時,它將開始搜索在會話創建期間指定的服務器列表。最終,當客戶端和至少一臺服務器之間的連接重新建立時,會話將再次轉換為“已連接”狀態(如果在會話超時值內重新連接)或將轉換為“過期”狀態(如果在會話超時后重新連接)。不建議為斷開連接創建新的會話對象(新的 ZooKeeper.class 或 c 綁定中的 zookeeper 句柄)。ZK 客戶端庫將為您處理重新連接。特別是我們在客戶端庫中內置了啟發式方法來處理諸如“羊群效應”之類的事情......
會話過期由 ZooKeeper 集群本身管理,而不是由客戶端管理。當 ZK 客戶端與集群建立會話時,它會提供上面詳述的“超時”值。集群使用此值來確定客戶端的會話何時到期。當集群在指定的會話超時期限內沒有收到來自客戶端的消息(即沒有心跳)時,就會發生過期。在會話到期時,集群將刪除該會話擁有的任何/所有臨時節點,并立即將更改通知任何/所有連接的客戶端(任何監視這些 znode 的人)。此時,過期會話的客戶端仍然與集群斷開連接,直到/除非它能夠重新建立與集群的連接,否則不會通知會話過期。
3.觀察者:?ZooKeeper 會話建立調用的另一個參數是默認觀察者。當客戶端發生任何狀態更改時,會通知觀察者。例如,如果客戶端失去與服務器的連接,客戶端將收到通知,或者如果客戶端的會話過期等......這個觀察者應該考慮斷開連接的初始狀態(即在任何狀態更改事件被發送給觀察者之前)客戶端庫)。在新連接的情況下,發送給觀察者的第一個事件通常是會話連接事件。
會話通過客戶端發送的請求保持活動狀態。如果會話空閑的時間會導致會話超時,客戶端將發送 PING 請求以保持會話活動。這個 PING 請求不僅允許 ZooKeeper 服務器知道客戶端仍然處于活動狀態,而且還允許客戶端驗證其與 ZooKeeper 服務器的連接是否仍然處于活動狀態。PING 的時間足夠保守,以確保有合理的時間來檢測死連接并重新連接到新服務器。
?
?
總結
以上是生活随笔為你收集整理的Zookeeper(1)-概述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么软件可以用蓝牙测试信号,litepo
- 下一篇: 前端学习便捷软件,插件