基本概念
角色
zookeeper 集群中的節(jié)點(diǎn)共有三種角色,每個(gè)節(jié)點(diǎn)同時(shí)只能是一種角色匈织。集群中的所有機(jī)器通過(guò)一個(gè) Leader 選舉過(guò)程來(lái)選定一臺(tái)被稱為 Leader 的機(jī)器到忽。
Leader:接受所有 Follower 的提案請(qǐng)求并統(tǒng)一協(xié)調(diào)發(fā)起提案的投票废离,負(fù)責(zé)與所有的 Follower 進(jìn)行內(nèi)部的數(shù)據(jù)交換
Follower:直接為客戶端服務(wù)并參與提案的投票庭呜,同時(shí)與 Leader 進(jìn)行數(shù)據(jù)交換
Observer:直接為客戶端服務(wù)但不參與提案的投票,同時(shí)也與 Leader 進(jìn)行數(shù)據(jù)交換會(huì)話
zookeeper 中客戶端啟動(dòng)時(shí)會(huì)與服務(wù)器建立一個(gè) TCP 連接搬男,從第一次連接建立開始,客戶端會(huì)話的生命周期就開始了彭沼,通過(guò)這個(gè)連接缔逛,客戶端能夠通過(guò)心跳檢測(cè)與服務(wù)器保持有效的會(huì)話,也能夠向服務(wù)器發(fā)送請(qǐng)求并接受響應(yīng),還能夠接收來(lái)自服務(wù)器的 watch 事件通知褐奴。節(jié)點(diǎn)
一般在分布式語(yǔ)境下的節(jié)點(diǎn)是指組成集群的每一臺(tái)服務(wù)器按脚,在 zookeeper 中還有另外一層意思,稱之為數(shù)據(jù)節(jié)點(diǎn)(ZNode)敦冬。
zookeeper 的整個(gè)名字空間的結(jié)構(gòu)是層次化的辅搬,和 Linux 文件系統(tǒng)結(jié)構(gòu)相似,是一顆樹脖旱。名字空間的層次由斜杠(/)來(lái)進(jìn)行分割堪遂,在名稱空間里面的每一個(gè)節(jié)點(diǎn)的名字空間由這個(gè)結(jié)點(diǎn)的路徑來(lái)確定。
每個(gè) ZNode 上都會(huì)保存自己的數(shù)據(jù)內(nèi)容萌庆,同時(shí)還會(huì)保存一系列屬性信息溶褪。版本
對(duì)于每個(gè) ZNode ,zookeeper 都會(huì)為它維護(hù)一個(gè)叫 Stat 的數(shù)據(jù)結(jié)構(gòu)践险,Stat 中記錄了 ZNode 的三個(gè)數(shù)據(jù)版本竿滨,version(當(dāng)前ZNode數(shù)據(jù)內(nèi)容的版本號(hào))、cversion(當(dāng)前ZNode子節(jié)點(diǎn)的版本號(hào))捏境、aversion(當(dāng)前ZNode的ACL變更版本號(hào))watcher
zookeeper 允許用戶在指定節(jié)點(diǎn)上注冊(cè)一些 watcher于游,并且在特定事件觸發(fā)的時(shí)候,zookeeper 服務(wù)端會(huì)將事件通知到感興趣的客戶端垫言,該機(jī)制是 zookeeper 實(shí)現(xiàn)分布式協(xié)調(diào)服務(wù)的重要特性贰剥。
客戶端命令
這里列出常用的客戶端命令,所謂客戶端命令指使用 zkCli 連接到 zookeeper 服務(wù)器之后使用的命令筷频,zkCli 連接的語(yǔ)法如下:
zkCli -server host:port cmd args
zkCli 是客戶端可執(zhí)行文件名蚌成,根據(jù)具體操作系統(tǒng)環(huán)境可能是 zkCli.sh 或 zkCli.cmd
host 是服務(wù)器IP或域名,port 是服務(wù)器端口號(hào)凛捏,如果有多個(gè)服務(wù)器地址則用逗號(hào)分隔
cmd 是具體命令担忧、args 是命令的參數(shù),也可以連接上服務(wù)器之后再執(zhí)行命令坯癣。
查看節(jié)點(diǎn)
ls /path
查看名為 /path 的子節(jié)點(diǎn)瓶盛,但只能查看指定節(jié)點(diǎn)下的第一級(jí)的所有子節(jié)點(diǎn)。
ls2 /path
查看名為 /path 的子節(jié)點(diǎn)示罗,并且能看到更新次數(shù)等屬性信息惩猫。創(chuàng)建節(jié)點(diǎn)
create [-s] [-e] /path data
創(chuàng)建一個(gè)名叫 /path 的節(jié)點(diǎn),并包含數(shù)據(jù) data蚜点。加上 -s 表示創(chuàng)建的是順序節(jié)點(diǎn)轧房,加上 -e 表示創(chuàng)建的是臨時(shí)節(jié)點(diǎn),如果都不加則默認(rèn)為創(chuàng)建持久節(jié)點(diǎn)绍绘。刪除節(jié)點(diǎn)
delete /path
刪除名為 /path 的節(jié)點(diǎn)設(shè)置節(jié)點(diǎn)數(shù)據(jù)
set /path data
設(shè)置名為 /path 的節(jié)點(diǎn)的數(shù)據(jù)為 data返回節(jié)點(diǎn)數(shù)據(jù)
get /path
返回名為 /path 的節(jié)點(diǎn)的數(shù)據(jù)和屬性信息強(qiáng)制同步數(shù)據(jù)
sync /path
將名為 /path 的節(jié)點(diǎn)強(qiáng)制同步為最新的數(shù)據(jù)幫助信息
help
幫助命令奶镶,顯示客戶端支持的命令及語(yǔ)法格式退出
quit
退出當(dāng)前客戶端迟赃,會(huì)話結(jié)束。
運(yùn)維命令
zookeeper 提供了一些四字命令用于獲取 zookeeper 服務(wù)端的當(dāng)前狀態(tài)及相關(guān)信息厂镇,這些命令在系統(tǒng)運(yùn)維時(shí)很有用捺氢。用戶在客戶端可以通過(guò) telnet 或 nc 向zookeeper 提交相應(yīng)的命令,比如 nc 方式:
echo cmd|nc host port
cmd 是具體的命令(因?yàn)橐话闶撬膫€(gè)字母所以又叫做四字命令)剪撬,host 是zookeeper 服務(wù)器 IP 地址或域名摄乒,port 是 zookeeper 端口號(hào)
conf
顯示服務(wù)配置的詳細(xì)信息,比如數(shù)據(jù)文件目錄残黑、日志文件目錄馍佑、間隔單位時(shí)間、選舉算法梨水、選舉端口等拭荤。cons
列出所有連接到服務(wù)器的客戶端的完全的連接/會(huì)話的詳細(xì)信息。包括”接受 / 發(fā)送”的包數(shù)量疫诽、會(huì)話 id 舅世、操作延遲、最后的操作執(zhí)行等奇徒。crst
重置所有連接雏亚。dump
列出未經(jīng)處理的會(huì)話和臨時(shí)節(jié)點(diǎn)。envi
顯示關(guān)于服務(wù)器環(huán)境的詳細(xì)信息摩钙,比如 zookeeper 版本罢低、操作系統(tǒng)版本、jdk 地址等胖笛。reqs
列出未經(jīng)處理的請(qǐng)求网持。ruok
測(cè)試服務(wù)是否處于正確狀態(tài)。如果確實(shí)如此长踊,那么服務(wù)返回“imok ”功舀,否則不做任何相應(yīng)。stat
輸出關(guān)于性能和連接的客戶端的列表身弊。wchs
列出服務(wù)器 watch 的詳細(xì)信息辟汰。wchc
通過(guò) session 列出服務(wù)器 watch 的詳細(xì)信息,它的輸出是一個(gè)與 watch 相關(guān)的會(huì)話的列表佑刷。wchp
通過(guò)路徑列出服務(wù)器 watch 的詳細(xì)信息莉擒,它的輸出是一個(gè)與 session 相關(guān)的路徑酿炸。
上面列出的是一些常用的四字命令瘫絮,更詳細(xì)信息可以參考zookeeper的官方文檔,里面的【ZooKeeper Commands】一節(jié)有具體介紹填硕。
特性
- 一致性
zookeeper 很好地保證在分布式高并發(fā)情況下節(jié)點(diǎn)的創(chuàng)建一定是全局唯一性麦萤,即保證客戶端無(wú)法重復(fù)創(chuàng)建一個(gè)已經(jīng)存在的數(shù)據(jù)節(jié)點(diǎn)鹿鳖。
根據(jù) CAP 理論,分布式系統(tǒng)只能滿足一致性(Consistence)壮莹、可用性(Availability)翅帜、分區(qū)容錯(cuò)性(partitioning)三項(xiàng)中的兩項(xiàng)而不可能滿足全部三項(xiàng)。對(duì)于 zookeeper 來(lái)說(shuō)命满,其實(shí)現(xiàn)了 A 可用性涝滴、P 分區(qū)容錯(cuò)性、C 中的寫入強(qiáng)一致性胶台,喪失的是 C 中的讀取一致性歼疮。
更進(jìn)一步解釋,zookeeper 的一致性保證包括以下幾點(diǎn):
- 順序一致性
一個(gè)客戶端的更新將按照發(fā)送的順序被寫入到服務(wù)端诈唬。 - 原子性
更新要么成功韩脏,要么失敗,沒有部分結(jié)果铸磅。 - 單一系統(tǒng)鏡像
客戶端只會(huì)連接 host 列表中狀態(tài)最新的那些實(shí)例赡矢。如果正在連接到的實(shí)例掛了,客戶端會(huì)嘗試重新連接到集群中的其他實(shí)例阅仔,那么此時(shí)滯后于故障實(shí)例的其它實(shí)例都不會(huì)接收該連接請(qǐng)求吹散,只有和故障實(shí)例版本相同或更新的實(shí)例才接收該連接請(qǐng)求。 - 持久性
寫操作完成之后將會(huì)被持久化存儲(chǔ)八酒,不受服務(wù)器故障影響送浊。 - 并發(fā)一致性
zookeeper 并不保證在某個(gè)時(shí)刻兩個(gè)不同客戶端具有一致的數(shù)據(jù)視圖,因?yàn)榫W(wǎng)絡(luò)的延遲一個(gè)客戶端可能在另一個(gè)客戶端得到修改通知之前進(jìn)行更新丘跌。如果不同客戶端讀取到相同的值很重要袭景,那么客戶端應(yīng)該在執(zhí)行讀取操作之前調(diào)用 sync() 方法,使得讀操作的連接所連的 zookeeper 實(shí)例能與 leader 進(jìn)行同步闭树,從而能讀到最新的類容耸棒。
watcher 監(jiān)聽
客戶端如果對(duì)一個(gè)節(jié)點(diǎn)注冊(cè) watcher 監(jiān)聽,那么當(dāng)該節(jié)點(diǎn)的內(nèi)容或其子節(jié)點(diǎn)發(fā)生變更時(shí)报辱,zookeeper 服務(wù)器會(huì)向訂閱的客戶端發(fā)送變更通知与殃。臨時(shí)節(jié)點(diǎn)
對(duì)在 zookeeper 上創(chuàng)建的臨時(shí)節(jié)點(diǎn),一旦客戶端與服務(wù)器之間的會(huì)話失效碍现,那么該臨時(shí)節(jié)點(diǎn)就被自動(dòng)清除幅疼。順序節(jié)點(diǎn)
客戶端申請(qǐng)創(chuàng)建該節(jié)點(diǎn)時(shí) zookeeper 會(huì)自動(dòng)在節(jié)點(diǎn)路徑末尾添加遞增序號(hào)
應(yīng)用場(chǎng)景
數(shù)據(jù)訂閱發(fā)布
將應(yīng)用中的配置信息放在 zookeeper 中集中管理。應(yīng)用在啟動(dòng)時(shí)主動(dòng)到zk服務(wù)端進(jìn)行一次配置信息的獲取昼接,同時(shí)在指定節(jié)點(diǎn)注冊(cè)一個(gè) watcher 監(jiān)聽爽篷。這樣只要配置信息發(fā)生變更,服務(wù)端都會(huì)實(shí)時(shí)通知到所有訂閱的客戶端慢睡。域名服務(wù)
將域名配置信息放在 zookeeper 上逐工,對(duì)外提供一套域名注冊(cè)铡溪、域名解析、域名可用性檢測(cè)的服務(wù)泪喊∽亓颍基于此提供一套動(dòng)態(tài)的 DNS 服務(wù)。全局唯一 ID
可以利用順序節(jié)點(diǎn)的特性生成全局唯一的 ID袒啼。分布式協(xié)調(diào)通知
利用 watcher 監(jiān)聽實(shí)現(xiàn)系統(tǒng)間的協(xié)調(diào)和通知哈扮,從而實(shí)現(xiàn)數(shù)據(jù)變更的處理。不同客戶端都對(duì) zookeeper 上同一個(gè)數(shù)據(jù)節(jié)點(diǎn)進(jìn)行 watcher 注冊(cè)蚓再,如果數(shù)據(jù)節(jié)點(diǎn)發(fā)生變化灶泵,那么所有訂閱的客戶端都能受到通知。Master 選舉
利用 zookeeper 創(chuàng)建節(jié)點(diǎn)時(shí)的強(qiáng)一致性对途,由客戶端集群定時(shí)往 zookeeper 上創(chuàng)建同一個(gè)名字的臨時(shí)節(jié)點(diǎn)赦邻。在這個(gè)過(guò)程中只有一個(gè)客戶端能夠創(chuàng)建成功,那么該客戶端就成了 Master实檀,同時(shí)其他沒有創(chuàng)建成功的客戶端都在該節(jié)點(diǎn)注冊(cè)一個(gè)節(jié)點(diǎn)變更的 watcher惶洲,用于監(jiān)控當(dāng)前 Master 機(jī)器是否存活,一旦發(fā)現(xiàn) Master 掛掉其余客戶端重新進(jìn)行 Master 選舉膳犹。分布式鎖
排他鎖
利用強(qiáng)一致性恬吕,將 zookeeper 上的一個(gè)臨時(shí)節(jié)點(diǎn)表示為一個(gè)排他鎖,所有客戶端同時(shí)創(chuàng)建該節(jié)點(diǎn)须床,最終只有一個(gè)客戶端能創(chuàng)建成功铐料,那么就認(rèn)為該客戶端獲得了鎖,同時(shí)注冊(cè)該節(jié)點(diǎn)的 watcher 監(jiān)聽豺旬。當(dāng)移除該節(jié)點(diǎn)就認(rèn)為釋放了鎖钠惩。共享鎖
利用強(qiáng)一致性,將 zookeeper 上的一個(gè)臨時(shí)順序節(jié)點(diǎn)表示為一個(gè)共享鎖族阅,并注冊(cè)同級(jí)子節(jié)點(diǎn)的 watcher 監(jiān)聽篓跛。判斷讀寫順序時(shí)根據(jù)不同需求關(guān)注比自己序號(hào)小的同級(jí)子節(jié)點(diǎn)類型。