一桐绒、什么是Zookeeper
ZooKeeper是一個(gè)為分布式應(yīng)用提供一致性服務(wù)的軟件夺脾,提供的功能包括:配置維護(hù)、域名服務(wù)茉继、分布式同步咧叭、組服務(wù)等。
它的核心是:文件系統(tǒng) + 通知機(jī)制
二烁竭、重要特點(diǎn)
一個(gè)領(lǐng)導(dǎo)者(Leader)菲茬,多個(gè)跟隨者(Follower)組成的集群
集群中只要有半數(shù)以上節(jié)點(diǎn)存活,Zookeeper集群就能正常服務(wù)
全局?jǐn)?shù)據(jù)一致性派撕,每個(gè)server保存一份相同的副本婉弹,client無(wú)論鏈接哪個(gè)server,得到的數(shù)據(jù)都是一致的
更新請(qǐng)求順序執(zhí)行终吼,來(lái)自同一個(gè)client的請(qǐng)求按順序執(zhí)行
數(shù)據(jù)更新原子性,一次數(shù)據(jù)更新要么成功要么失敗
實(shí)時(shí)性衔峰,在一定時(shí)間范圍內(nèi)垫卤,client能讀到最新數(shù)據(jù)
三穴肘、數(shù)據(jù)結(jié)構(gòu)
ZooKeeper數(shù)據(jù)模型的結(jié)構(gòu)與Unix文件系統(tǒng)很類似,整體上可看作是一棵樹(shù)豹缀,每個(gè)節(jié)點(diǎn)稱作一個(gè)?ZNode邢笙。每個(gè)?ZNode默認(rèn)能存儲(chǔ)1MB數(shù)據(jù)氮惯,每個(gè)?ZNode都可以通過(guò)其路徑唯一標(biāo)識(shí)。
四帘不、應(yīng)用場(chǎng)景(※)
分布式鎖
服務(wù)注冊(cè)和發(fā)現(xiàn)
利用?Znode和?Watcher,可以實(shí)現(xiàn)分布式服務(wù)的注冊(cè)和發(fā)現(xiàn)捣郊。最著名的應(yīng)用就是阿里的分布式?RPC框架?Dubbo慈参。
共享配置和狀態(tài)信息
Redis的分布式解決方案?Codis(豌豆莢)模她,就利用了?Zookeeper來(lái)存放數(shù)據(jù)路由表和?codis-proxy?節(jié)點(diǎn)的元信息侈净。同時(shí)?codis-config?發(fā)起的命令都會(huì)通過(guò)?ZooKeeper?同步到各個(gè)存活的?codis-proxy畜侦。
五躯保、選舉機(jī)制(※)
5.1 半數(shù)機(jī)制(paxos協(xié)議)
集群中半數(shù)以上機(jī)器存活,集群可用途事,所以Zookeeper適合安裝奇數(shù)臺(tái)服務(wù)器
5.2 內(nèi)部選舉步驟
在分布式系統(tǒng)中選主最直接或者傳統(tǒng)的方法是直接選定集群的一個(gè)節(jié)點(diǎn)為leader,其它的節(jié)點(diǎn)為follower义图,這樣引入的一個(gè)問(wèn)題是如果leader節(jié)點(diǎn)掛掉召烂,整個(gè)集群就掛掉了奏夫。所以我們需要一種自動(dòng)選主算法酗昼,如果leader節(jié)點(diǎn)掛掉,則從follower節(jié)點(diǎn)中選出一個(gè)主節(jié)點(diǎn)蒸痹。
1. 選舉階段 Leader election
最大ZXID也就是節(jié)點(diǎn)本地的最新事務(wù)編號(hào)电抚,包含epoch和計(jì)數(shù)兩部分蝙叛。epoch是紀(jì)元的意思借帘,相當(dāng)于Raft算法選主時(shí)候的term淌铐,標(biāo)識(shí)當(dāng)前l(fā)eader周期腿准,每次選舉一個(gè)新的Leader服務(wù)器后吐葱,會(huì)生成一個(gè)新的epoch
所有節(jié)點(diǎn)處于Looking狀態(tài),各自依次發(fā)起投票灾前,投票包含自己的服務(wù)器ID和最新事務(wù)ID(ZXID)哎甲。
如果發(fā)現(xiàn)別人的?ZXID比自己大炭玫,也就是數(shù)據(jù)比自己新貌虾,那么就重新發(fā)起投票,投票給目前已知最大的?ZXID所屬節(jié)點(diǎn)榴鼎。
每次投票后巫财,服務(wù)器都會(huì)統(tǒng)計(jì)投票數(shù)量哩陕,判斷是否有某個(gè)節(jié)點(diǎn)得到半數(shù)以上的投票。如果存在這樣的節(jié)點(diǎn)闽瓢,該節(jié)點(diǎn)將會(huì)成為準(zhǔn)Leader,狀態(tài)變?yōu)?Leading缺猛。其他節(jié)點(diǎn)的狀態(tài)變?yōu)镕ollowing荔燎。
2. 發(fā)現(xiàn)階段 Discovery
為了防止某些意外情況有咨,比如因網(wǎng)絡(luò)原因在上一階段產(chǎn)生多個(gè)?Leader的情況蒸健。
Leader集思廣益似忧,接收所有?Follower發(fā)來(lái)各自的最新?epoch值橡娄。?Leader從中選出最大的?epoch,基于此值加1滤祖,生成新的?epoch分發(fā)給各個(gè)?Follower匠童。
各個(gè)?Follower收到全新的?epoch后塑顺,返回?ACK給?Leader严拒,帶上各自最大的?ZXID和歷史事務(wù)日志。?Leader選出最大的?ZXID挤牛,并更新自身歷史日志墓赴。
3. 同步階段 Synchronization
Leader剛才收集得到的最新歷史事務(wù)日志,同步給集群中所有的Follower坦辟。只有當(dāng)半數(shù)Follower同步成功锉走,這個(gè)準(zhǔn)Leader才能成為正式的Leader。
六疮绷、ZNode 內(nèi)構(gòu)
6.1 節(jié)點(diǎn)類型
持久persistent:client 和 server 斷開(kāi)連接后冬骚,創(chuàng)建的節(jié)點(diǎn)不刪除
短暫ephemeral:client 和 server 斷開(kāi)連接后,創(chuàng)建的節(jié)點(diǎn)自己刪除
另外分?有序和無(wú)序兩種節(jié)點(diǎn)庇麦。創(chuàng)建有序節(jié)點(diǎn)時(shí)山橄,會(huì)自動(dòng)將節(jié)點(diǎn)名增加序列號(hào)航棱,例如
$ create -s /test/no1 "no1"
Created /test/no10000000000
6.1 內(nèi)部結(jié)構(gòu)
data: ZNode存儲(chǔ)的數(shù)據(jù)信息饮醇,每個(gè)節(jié)點(diǎn)數(shù)據(jù)最大不超過(guò)1MB
ACL(Access Control List): 記錄訪問(wèn)權(quán)限秕豫,哪些人或哪些IP可訪問(wèn)本節(jié)點(diǎn)
child: 當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)
stat: 各種元數(shù)據(jù),比如事務(wù)ID祠墅、版本號(hào)饵隙、時(shí)間戳金矛、大小等
czxid- 引起這個(gè) znode 創(chuàng)建的 zxid,創(chuàng)建節(jié)點(diǎn)的事務(wù)的 zxid
ctime - znode 被創(chuàng)建的毫秒數(shù)
mzxid - znode 最后更新的 zxid
mtime - znode 最后修改的毫秒數(shù)
pZxid-znode 最后更新的子節(jié)點(diǎn) zxid
cversion - znode 子節(jié)點(diǎn)變化號(hào)娶耍,znode 子節(jié)點(diǎn)修改次數(shù)
dataversion - znode 數(shù)據(jù)變化號(hào)
aclVersion - znode 訪問(wèn)控制列表的變化號(hào)
ephemeralOwner- 如果是臨時(shí)節(jié)點(diǎn)榕酒,這個(gè)是znode擁有者的 session id想鹰。如果不是臨時(shí)節(jié)點(diǎn)則是 0药版。
dataLength- znode 的數(shù)據(jù)長(zhǎng)度
numChildren - znode 子節(jié)點(diǎn)數(shù)量
七何缓、監(jiān)聽(tīng)器原理(※)
客戶端服務(wù)端
Main進(jìn)程
創(chuàng)建ZK客戶端碌廓,會(huì)創(chuàng)建connet網(wǎng)絡(luò)連接通信線程剩盒,listener監(jiān)聽(tīng)線程
通過(guò)connect線程將注冊(cè)的監(jiān)聽(tīng)事件發(fā)送給Zookeeper服務(wù)端
將監(jiān)聽(tīng)事件添加到注冊(cè)監(jiān)聽(tīng)器列表
監(jiān)聽(tīng)到有數(shù)據(jù)或路徑變化波材,將消息發(fā)送給listener
listener線程內(nèi)部調(diào)用process方法
常見(jiàn)監(jiān)聽(tīng)
子節(jié)點(diǎn)增減變化(如下示例)
節(jié)點(diǎn)數(shù)據(jù)變化
八、寫數(shù)據(jù)流程
客戶端發(fā)出寫入數(shù)據(jù)請(qǐng)求給任意Follower贾铝。
Follower把寫入數(shù)據(jù)請(qǐng)求轉(zhuǎn)發(fā)給Leader垢揩。
Leader采用二階段提交方式,先發(fā)送Propose廣播給Follower斑匪。
Follower接到Propose消息蚀瘸,寫入日志成功后,返回ACK消息給Leader贮勃。
Leader接到半數(shù)以上ACK消息贪惹,返回成功給客戶端,并且廣播Commit請(qǐng)求給Follower
參考
《從Paxos到ZooKeeper》經(jīng)典
二奏瞬、zookeeper 集群搭建