Zookeeper學(xué)習(xí)筆記(一)
1.zookeeper是什么?
1.1 zookeeper概覽
zookeeper是一個(gè)分布式服務(wù)框架荔仁,是Apache Hadoop的一個(gè)子項(xiàng)目,它主要用來(lái)解決分布式應(yīng)用中經(jīng)常遇到的一些數(shù)據(jù)管理問(wèn)題卖毁,如:統(tǒng)一命名服務(wù)错妖、狀態(tài)同步服務(wù)痴施、集群管理、分布式應(yīng)用配置項(xiàng)的管理等全跨。Zookeeper也實(shí)現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱天梧、負(fù)載均衡呢岗、分布式協(xié)調(diào)/通知、分布式鎖和分布式隊(duì)列等功能蚯妇。
1.2 分布式系統(tǒng)的協(xié)調(diào)工作
分布式系統(tǒng)的協(xié)調(diào)工作就是通過(guò)某種方式敷燎,讓每個(gè)節(jié)點(diǎn)的信息能夠同步和共享暂筝,這依賴于服務(wù)進(jìn)程之間的通信箩言,通信方式有兩種:
1.通過(guò)網(wǎng)絡(luò)進(jìn)行信息共享
通過(guò)人與人之間的直接溝通完成任務(wù)的下達(dá)和傳遞,比如在項(xiàng)目開發(fā)過(guò)程中焕襟,當(dāng)任務(wù)分配有變化時(shí)陨收,leader會(huì)單獨(dú)告訴組員或者召開會(huì)議。
2.通過(guò)共享存儲(chǔ)
將任務(wù)分配的更新信息提交到中央存儲(chǔ)上鸵赖,而組員可以每天從中央存儲(chǔ)务漩,比如SVN這種,拉取最新的任務(wù)分配表它褪,保證每次更新組員都能第一時(shí)間獲取最新的信息饵骨。
1.3 zookeeper如何實(shí)現(xiàn)分布式系統(tǒng)的協(xié)調(diào)
zookeeper針對(duì)分布式系統(tǒng)的協(xié)調(diào),使用的是第二種方式茫打,共享存儲(chǔ)居触。
當(dāng)主節(jié)點(diǎn)也就是leader對(duì)某個(gè)從節(jié)點(diǎn)的分工信息做出了改變時(shí),相關(guān)訂閱的從節(jié)點(diǎn)會(huì)得到zookeeper的通知老赤,取得自己最新的任務(wù)分配轮洋,完成工作后,把完成情況提交到zookeepeer抬旺,主節(jié)點(diǎn)訂閱了該任務(wù)的完成情況信息弊予,所以得到zookeeper的完工的通知。(注:slave節(jié)點(diǎn)想要獲取Zookeeper的更新通知开财,需事先在關(guān)心的數(shù)據(jù)節(jié)點(diǎn)上設(shè)置觀察點(diǎn))
此處參考:https://blog.csdn.net/liyiming2017/article/details/83035157
1.4 zookeeper的相關(guān)概念
1.4.1 znode
zookeeper采用了類似文件系統(tǒng)的層級(jí)樹狀結(jié)構(gòu)進(jìn)行管理汉柒,zookeeper所保存的任務(wù)分配,完成情況等共享信息都被保存在一個(gè)個(gè)節(jié)點(diǎn)上责鳍,這些節(jié)點(diǎn)被稱為znode碾褂。
根節(jié)點(diǎn) " / " 包含4個(gè)子節(jié)點(diǎn),其中三個(gè)擁有下一級(jí)節(jié)點(diǎn)薇搁。有的葉子節(jié)點(diǎn)存儲(chǔ)了信息斋扰。而有的節(jié)點(diǎn)上沒(méi)有存儲(chǔ)數(shù)據(jù)但也有著重要含義,比如/master下沒(méi)有數(shù)據(jù)代表著分布式應(yīng)用的主節(jié)點(diǎn)還沒(méi)有被選舉出來(lái)。znode節(jié)點(diǎn)存儲(chǔ)的數(shù)據(jù)為字節(jié)數(shù)組传货,存儲(chǔ)數(shù)據(jù)的格式?jīng)]有限制屎鳍,也不提供解析,需要應(yīng)用自己實(shí)現(xiàn)问裕。
- /master逮壁,存儲(chǔ)了當(dāng)前主節(jié)點(diǎn)的信息
- /workers,下面的每個(gè)子znode代表一個(gè)從節(jié)點(diǎn)粮宛,子znode上存儲(chǔ)的數(shù)據(jù)窥淆,如“foo.com:2181”,代表從節(jié)點(diǎn)的信息巍杈。
- /tasks忧饭,下面的每個(gè)子znode代表一個(gè)任務(wù),子znode上存儲(chǔ)的信息如“run cmd”筷畦,代表該內(nèi)務(wù)內(nèi)容
- /assign词裤,下面每個(gè)子znode代表一個(gè)從節(jié)點(diǎn)的任務(wù)集合。如/assign/worker-1鳖宾,代表worker-1這個(gè)從節(jié)點(diǎn)的任務(wù)集合吼砂。/assign/worker-1下的每個(gè)子znode代表分配給worker-1的一個(gè)任務(wù)。
znode的類型
持久節(jié)點(diǎn)(persistent)和臨時(shí)節(jié)點(diǎn)(ephemeral)
持久節(jié)點(diǎn)只能通過(guò)delete刪除鼎文,而臨時(shí)節(jié)點(diǎn)在創(chuàng)建該節(jié)點(diǎn)的客戶端崩潰或關(guān)閉時(shí)渔肩,自動(dòng)被刪除。通俗的講拇惋,在客戶端與zookeeper斷開連接后周偎,持久化目錄節(jié)點(diǎn)依然存在,而臨時(shí)目錄節(jié)點(diǎn)被刪除蚤假。有序節(jié)點(diǎn)
znode可以被設(shè)置為有序(sequentional)節(jié)點(diǎn)栏饮,有序的znode節(jié)點(diǎn)會(huì)被分配一個(gè)唯一的遞增的證書,如果創(chuàng)建了一個(gè)名為worker-的有序節(jié)點(diǎn)磷仰,zk會(huì)自動(dòng)分配一個(gè)1在它后面袍嬉,名稱變?yōu)閣orker-1,通過(guò)這種方式可以保證znode名稱的唯一性灶平,且方便看到節(jié)點(diǎn)創(chuàng)建的順序伺通。
znode一些操作的API
create /path data //創(chuàng)建一個(gè)名為/path的znode,數(shù)據(jù)為data
delete /path //刪除名為/path的znode
exists /path //檢查是否存在名為/path的znode
setData /path data //設(shè)置名為/path的znode的數(shù)據(jù)為data
getData /path //返回名為/path的znode的數(shù)據(jù)
getChildren /path //返回所有/path節(jié)點(diǎn)的所有子節(jié)點(diǎn)列表
1.4.2 觀察和通知(Watcher)
Watcher(事件監(jiān)聽(tīng)器)逢享,是zk中的一個(gè)很重要的特性罐监,zk允許用戶在指定節(jié)點(diǎn)上注冊(cè)一些Watcher,并且在一些特定事件觸發(fā)的時(shí)候瞒爬,zk服務(wù)端會(huì)將事件通知到感興趣的客戶端上去弓柱,該機(jī)制是zk實(shí)現(xiàn)分布式協(xié)調(diào)服務(wù)的重要特性沟堡。
使用zk時(shí)不能期望能夠監(jiān)控到節(jié)點(diǎn)每次的變化,因?yàn)槊看卧O(shè)置觀察點(diǎn)矢空,觀察點(diǎn)在觸發(fā)一次之后立即失效航罗,觀察點(diǎn)一旦被觸發(fā),就需要再次設(shè)置新的觀察點(diǎn)屁药。所以當(dāng)客戶端C1在處理第一次觸發(fā)的邏輯時(shí)粥血,C2更新了tasks,那么C1不會(huì)得到新的通知酿箭,要想不錯(cuò)過(guò)复亏,C1需要在設(shè)置監(jiān)視點(diǎn)之前讀取/tasks的數(shù)據(jù),進(jìn)行對(duì)比缭嫡,發(fā)現(xiàn)更新缔御。
zookeeper只能保證最終一致性,而不能保證強(qiáng)一致性
械巡,其達(dá)到最終一致性有兩種方式:(1)再次設(shè)置觀察點(diǎn)前再取一次數(shù)據(jù)和通知時(shí)取到的數(shù)據(jù)對(duì)比刹淌,發(fā)現(xiàn)變化了再執(zhí)行邏輯(2)什么也不做,只是等再次變化時(shí)獲取通知讥耗,最終一致。兩者的區(qū)別是中間的時(shí)間差疹启,具體如何選擇取決于系統(tǒng)能否忍耐這個(gè)時(shí)間差古程。
zookeeper也可以定義不同的觀察類型,如觀察znode數(shù)據(jù)變化喊崖,或觀察znode子節(jié)點(diǎn)變化挣磨,觀察znode創(chuàng)建或者刪除。
1.4.3 版本
對(duì)于每一個(gè)znode荤懂,zookeeper都會(huì)為其維護(hù)一個(gè)叫做Stat的數(shù)據(jù)結(jié)構(gòu)茁裙,它記錄了這個(gè)znode的三個(gè)數(shù)據(jù)版本,分別是version(當(dāng)前znode的版本)节仿,cversion(當(dāng)前znode子節(jié)點(diǎn)的版本)和cversion(當(dāng)前znode的ACL版本)晤锥。
版本號(hào)隨著每次數(shù)據(jù)變化遞增,setData和delete操作以版本號(hào)作為參數(shù)廊宪,當(dāng)傳入的版本號(hào)與服務(wù)器上不一致時(shí)矾瘾,會(huì)調(diào)用失敗。當(dāng)多個(gè)zk客戶端同時(shí)對(duì)一個(gè)znode操作時(shí)箭启,版本會(huì)起到有效避免分布式更新的并發(fā)問(wèn)題的作用壕翩。
1.4.4 法定人數(shù)
zookeeper服務(wù)器運(yùn)行于兩種模式:獨(dú)立模式和仲裁模式(集群)。仲裁模式下傅寡,會(huì)復(fù)制所有服務(wù)器的數(shù)據(jù)樹放妈。但如果讓客戶端等待所有復(fù)制完成北救,延遲太高。這里引入法定人數(shù)概念芜抒,指為了使zookeeper集群正常工作扭倾,必須有效運(yùn)行的服務(wù)器數(shù)量。同時(shí)也是服務(wù)器通知客戶端保存成功前挽绩,必須保存數(shù)據(jù)的服務(wù)器最小數(shù)膛壹。例如我們有一個(gè)5臺(tái)服務(wù)器的zookeeper集群,法定人數(shù)為3唉堪,只要任何3個(gè)服務(wù)器保存了數(shù)據(jù)模聋,客戶端就會(huì)收到確認(rèn)。只要有3臺(tái)服務(wù)器存活唠亚,整個(gè)zookeeper集群就是可用的链方。
下圖展示了客戶端提交請(qǐng)求到收到回復(fù)的過(guò)程:
法定人數(shù)需要大于服務(wù)器數(shù)量的一半。也稱為多數(shù)原則灶搜。舉個(gè)例子說(shuō)明祟蚀,假如集群有5臺(tái)服務(wù)器,法定人數(shù)為2割卖,那么有2臺(tái)服務(wù)器參與復(fù)制即可前酿,若這2臺(tái)server剛剛復(fù)制完/z這個(gè)znode,就掛掉了鹏溯。此時(shí)剩下了3臺(tái)server罢维,大于法定人數(shù)2,所以zookeeper認(rèn)為集群正常(當(dāng)集群中存活的服務(wù)器數(shù)量大于等于法定人數(shù)丙挽,zookeeper認(rèn)為集群正常)肺孵,但這三臺(tái)服務(wù)器是無(wú)法發(fā)現(xiàn)/z這個(gè)znode的。如果法定人數(shù)大于服務(wù)器數(shù)量一半颜阐,那么法定人數(shù)復(fù)制完成平窘,就可以確保集群存活時(shí),至少有一臺(tái)服務(wù)器有最新的znode凳怨,否則集群認(rèn)為自己已經(jīng)崩潰瑰艘。
引用https://blog.csdn.net/liyiming2017/article/details/83035157
1.4.5 會(huì)話(Session)
Session 指的是 ZooKeeper 服務(wù)器與客戶端會(huì)話。在 ZooKeeper 中猿棉,一個(gè)客戶端連接是指客戶端和服務(wù)器之間的一個(gè) TCP 長(zhǎng)連接磅叛。客戶端啟動(dòng)的時(shí)候萨赁,首先會(huì)與服務(wù)器建立一個(gè) TCP 連接弊琴,從第一次連接建立開始,客戶端會(huì)話的生命周期也開始了杖爽。通過(guò)這個(gè)連接敲董,客戶端能夠通過(guò)心跳檢測(cè)與服務(wù)器保持有效的會(huì)話紫皇,也能夠向Zookeeper服務(wù)器發(fā)送請(qǐng)求并接受響應(yīng),同時(shí)還能夠通過(guò)該連接接收來(lái)自服務(wù)器的Watch事件通知腋寨。Session的sessionTimeout值用來(lái)設(shè)置一個(gè)客戶端會(huì)話的超時(shí)時(shí)間聪铺。當(dāng)由于服務(wù)器壓力太大、網(wǎng)絡(luò)故障或是客戶端主動(dòng)斷開連接等各種原因?qū)е驴蛻舳诉B接斷開時(shí)萄窜,只要在sessionTimeout規(guī)定的時(shí)間內(nèi)能夠重新連接上集群中任意一臺(tái)服務(wù)器铃剔,那么之前創(chuàng)建的會(huì)話仍然有效。
在為客戶端創(chuàng)建會(huì)話之前查刻,服務(wù)端首先會(huì)為每個(gè)客戶端都分配一個(gè)sessionID键兜。由于 sessionID 是 Zookeeper 會(huì)話的一個(gè)重要標(biāo)識(shí),許多與會(huì)話相關(guān)的運(yùn)行機(jī)制都是基于這個(gè) sessionID 的穗泵,因此普气,無(wú)論是哪臺(tái)服務(wù)器為客戶端分配的 sessionID,都務(wù)必保證全局唯一佃延。
如何保證session全局唯一现诀?
保證sessionId全局唯一的基本思想是機(jī)器標(biāo)識(shí)+隨機(jī)數(shù)(時(shí)間戳),機(jī)器標(biāo)識(shí)用來(lái)區(qū)分集群中不同的機(jī)器履肃,同一臺(tái)機(jī)器內(nèi)的session可以用隨機(jī)數(shù)仔沿、內(nèi)存地址、計(jì)數(shù)器等多種手段來(lái)區(qū)分榆浓。
1.4.6 ACL
zookeeper采用ACL(AccessControlLists)策略來(lái)進(jìn)行權(quán)限控制于未,類似于UNIX文件系統(tǒng)的權(quán)限控制,Zookeeper定義了5種權(quán)限:
- CREATE:創(chuàng)建子節(jié)點(diǎn)的權(quán)限
- READ:獲取節(jié)點(diǎn)數(shù)據(jù)和子節(jié)點(diǎn)列表的權(quán)限
- WRITE:更新節(jié)點(diǎn)數(shù)據(jù)的權(quán)限
- DELETE:刪除子節(jié)點(diǎn)的權(quán)限
- ADMIN:設(shè)置節(jié)點(diǎn)ACL的權(quán)限
注:CREATE和DELETE都是針對(duì)子節(jié)點(diǎn)的權(quán)限控制陡鹃。
參考:
http://www.reibang.com/p/93b3818434d3
https://blog.csdn.net/liyiming2017/article/details/83035157
https://blog.csdn.net/yangguosb/article/details/78262518