前言
ZooKeeper 是一個(gè)分布式的莉钙,開(kāi)放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù)嵌莉。它是一個(gè)為分布式應(yīng)用提供一致性服務(wù)的軟件进萄,提供的功能包括:配置維護(hù)、域名服務(wù)烦秩、分布式同步垮斯、組服務(wù)等。
ZooKeeper 的目標(biāo)就是封裝好復(fù)雜易出錯(cuò)的關(guān)鍵服務(wù)只祠,將簡(jiǎn)單易用的接口和性能高效兜蠕、功能穩(wěn)定的系統(tǒng)提供給用戶。
面試題
- ZooKeeper 是什么抛寝?
- ZooKeeper 提供了什么熊杨?
- Zookeeper 文件系統(tǒng)
- ZAB 協(xié)議?
- 四種類型的數(shù)據(jù)節(jié)點(diǎn) Znode
- Zookeeper Watcher 機(jī)制 -- 數(shù)據(jù)變更通知
- 客戶端注冊(cè) Watcher 實(shí)現(xiàn)
- 服務(wù)端處理 Watcher 實(shí)現(xiàn)
- 客戶端回調(diào) Watcher
- ACL 權(quán)限控制機(jī)制
- Chroot 特性
- 會(huì)話管理
- 服務(wù)器角色
- Zookeeper 下 Server 工作狀態(tài)
- 數(shù)據(jù)同步
- zookeeper 是如何保證事務(wù)的順序一致性的盗舰?
- 分布式集群中為什么會(huì)有 Master晶府?
- zk 節(jié)點(diǎn)宕機(jī)如何處理?
- zookeeper 負(fù)載均衡和 nginx 負(fù)載均衡區(qū)別
- Zookeeper 有哪幾種幾種部署模式钻趋?
- 集群最少要幾臺(tái)機(jī)器川陆,集群規(guī)則是怎樣的?
- 集群支持動(dòng)態(tài)添加機(jī)器嗎?
- Zookeeper 對(duì)節(jié)點(diǎn)的 watch 監(jiān)聽(tīng)通知是永久的嗎蛮位?為什么不是永久的?
- Zookeeper 的 java 客戶端都有哪些较沪?
- chubby 是什么,和 zookeeper 比你怎么看失仁?
- 說(shuō)幾個(gè) zookeeper 常用的命令尸曼。
- ZAB 和 Paxos 算法的聯(lián)系與區(qū)別?
- Zookeeper 的典型應(yīng)用場(chǎng)景
1. ZooKeeper 是什么萄焦?
ZooKeeper 是一個(gè)開(kāi)放源碼的分布式協(xié)調(diào)服務(wù)控轿,它是集群的管理者,監(jiān)視著集群中各個(gè)節(jié)點(diǎn)的狀態(tài)根據(jù)節(jié)點(diǎn)提交的反饋進(jìn)行下一步合理操作。最終茬射,將簡(jiǎn)單易用的接口和性能高效鹦蠕、功能穩(wěn)定的系統(tǒng)提供給用戶。
分布式應(yīng)用程序可以基于 Zookeeper 實(shí)現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱躲株、負(fù)載均衡片部、命名服務(wù)、分布式協(xié)調(diào)/通知霜定、集群管理、Master 選舉廊鸥、分布式鎖和分布式隊(duì)列等功能望浩。
Zookeeper 保證了如下分布式一致性特性:
(1)順序一致性
(2)原子性
(3)單一視圖
(4)可靠性
(5)實(shí)時(shí)性(最終一致性)
客戶端的讀請(qǐng)求可以被集群中的任意一臺(tái)機(jī)器處理,如果讀請(qǐng)求在節(jié)點(diǎn)上注冊(cè)了監(jiān)聽(tīng)器惰说,這個(gè)監(jiān)聽(tīng)器也是由所連接的 zookeeper 機(jī)器來(lái)處理磨德。
對(duì)于寫請(qǐng)求,這些請(qǐng)求會(huì)同時(shí)發(fā)給其他 zookeeper 機(jī)器并且達(dá)成一致后吆视,請(qǐng)求才會(huì)返回成功典挑。
因此,隨著 zookeeper 的集群機(jī)器增多啦吧,讀請(qǐng)求的吞吐會(huì)提高但是寫請(qǐng)求的吞吐會(huì)下降您觉。
有序性是 zookeeper 中非常重要的一個(gè)特性,所有的更新都是全局有序的授滓,每個(gè)更新都有一個(gè)唯一的時(shí)間戳琳水,這個(gè)時(shí)間戳稱為 zxid(Zookeeper Transaction Id)。
而讀請(qǐng)求只會(huì)相對(duì)于更新有序般堆,也就是讀請(qǐng)求的返回結(jié)果中會(huì)帶有這個(gè)zookeeper 最新的 zxid邑退。
2. ZooKeeper 提供了什么踏施?
(1)文件系統(tǒng)
(2)通知機(jī)制
3.Zookeeper 文件系統(tǒng)
Zookeeper 提供一個(gè)多層級(jí)的節(jié)點(diǎn)命名空間(節(jié)點(diǎn)稱為 znode)。
與文件系統(tǒng)不同的是,這些節(jié)點(diǎn)都可以設(shè)置關(guān)聯(lián)的數(shù)據(jù)三娩,而文件系統(tǒng)中只有文件節(jié)點(diǎn)可以存放數(shù)據(jù)而目錄節(jié)點(diǎn)不行。
Zookeeper 為了保證高吞吐和低延遲删窒,在內(nèi)存中維護(hù)了這個(gè)樹(shù)狀的目錄結(jié)構(gòu)舟误,這種特性使得 Zookeeper 不能用于存放大量的數(shù)據(jù),每個(gè)節(jié)點(diǎn)的存放數(shù)據(jù)上限為1M胃碾。
4. ZAB 協(xié)議涨享?
ZAB 協(xié)議是為分布式協(xié)調(diào)服務(wù) Zookeeper 專門設(shè)計(jì)的一種支持崩潰恢復(fù)的原子廣播協(xié)議。
ZAB 協(xié)議包括兩種基本的模式:崩潰恢復(fù)和消息廣播仆百。
當(dāng)整個(gè) zookeeper 集群剛剛啟動(dòng)或者 Leader 服務(wù)器宕機(jī)厕隧、重啟或者網(wǎng)絡(luò)故障導(dǎo)致不存在過(guò)半的服務(wù)器與 Leader 服務(wù)器保持正常通信時(shí),所有進(jìn)程(服務(wù)器)進(jìn)入崩潰恢復(fù)模式,首先選舉產(chǎn)生新的 Leader 服務(wù)器吁讨,然后集群中 Follower 服務(wù)器開(kāi)始與新的 Leader 服務(wù)器進(jìn)行數(shù)據(jù)同步髓迎,當(dāng)集群中超過(guò)半數(shù)機(jī)器與該 Leader服務(wù)器完成數(shù)據(jù)同步之后,退出恢復(fù)模式進(jìn)入消息廣播模式建丧,Leader 服務(wù)器開(kāi)始接收客戶端的事務(wù)請(qǐng)求生成事物提案來(lái)進(jìn)行事務(wù)請(qǐng)求處理排龄。
5. 四種類型的數(shù)據(jù)節(jié)點(diǎn) Znode
(1)PERSISTENT-持久節(jié)點(diǎn)
除非手動(dòng)刪除,否則節(jié)點(diǎn)一直存在于 Zookeeper 上
(2)EPHEMERAL-臨時(shí)節(jié)點(diǎn)
臨時(shí)節(jié)點(diǎn)的生命周期與客戶端會(huì)話綁定翎朱,一旦客戶端會(huì)話失效(客戶端與zookeeper 連接斷開(kāi)不一定會(huì)話失效)橄维,那么這個(gè)客戶端創(chuàng)建的所有臨時(shí)節(jié)點(diǎn)都會(huì)被移除。
(3)PERSISTENT_SEQUENTIAL-持久順序節(jié)點(diǎn)
基本特性同持久節(jié)點(diǎn)拴曲,只是增加了順序?qū)傩哉瑁?jié)點(diǎn)名后邊會(huì)追加一個(gè)由父節(jié)點(diǎn)維護(hù)的自增整型數(shù)字。
(4)EPHEMERAL_SEQUENTIAL-臨時(shí)順序節(jié)點(diǎn)
基本特性同臨時(shí)節(jié)點(diǎn)澈灼,增加了順序?qū)傩跃捍ǎ?jié)點(diǎn)名后邊會(huì)追加一個(gè)由父節(jié)點(diǎn)維護(hù)的自增整型數(shù)字。
6. Zookeeper Watcher 機(jī)制 -- 數(shù)據(jù)變更通知
Zookeeper 允許客戶端向服務(wù)端的某個(gè) Znode 注冊(cè)一個(gè) Watcher 監(jiān)聽(tīng)叁熔,當(dāng)服務(wù)端的一些指定事件觸發(fā)了這個(gè) Watcher委乌,服務(wù)端會(huì)向指定客戶端發(fā)送一個(gè)事件通知來(lái)實(shí)現(xiàn)分布式的通知功能,然后客戶端根據(jù) Watcher 通知狀態(tài)和事件類型做出業(yè)務(wù)上的改變荣回。
工作機(jī)制:
(1)客戶端注冊(cè) watcher
(2)服務(wù)端處理 watcher
(3)客戶端回調(diào) watcher
Watcher 特性總結(jié):
(1)一次性
無(wú)論是服務(wù)端還是客戶端遭贸,一旦一個(gè) Watcher 被 觸 發(fā) ,Zookeeper 都會(huì)將其從相應(yīng)的存儲(chǔ)中移除驹马。這樣的設(shè)計(jì)有效的減輕了服務(wù)端的壓力革砸,不然對(duì)于更新非常頻繁的節(jié)點(diǎn),服務(wù)端會(huì)不斷的向客戶端發(fā)送事件通知糯累,無(wú)論對(duì)于網(wǎng)絡(luò)還是服務(wù)端的壓力都非常大算利。
(2)客戶端串行執(zhí)行
客戶端 Watcher 回調(diào)的過(guò)程是一個(gè)串行同步的過(guò)程。
(3)輕量
3.1泳姐、Watcher 通知非常簡(jiǎn)單效拭,只會(huì)告訴客戶端發(fā)生了事件,而不會(huì)說(shuō)明事件的具體內(nèi)容胖秒。
3.2缎患、客戶端向服務(wù)端注冊(cè) Watcher 的時(shí)候,并不會(huì)把客戶端真實(shí)的 Watcher 對(duì)象實(shí)體傳遞到服務(wù)端阎肝,僅僅是在客戶端請(qǐng)求中使用 boolean 類型屬性進(jìn)行了標(biāo)記挤渔。
(4)Zookeeper 只能保證最終的一致性,而無(wú)法保證強(qiáng)一致性
watcher event 異步發(fā)送 watcher 的通知事件從 server 發(fā)送到 client 是異步的风题,這就存在一個(gè)問(wèn)題判导,不同的客戶端和服務(wù)器之間通過(guò) socket 進(jìn)行通信嫉父,由于網(wǎng)絡(luò)延遲或其他因素導(dǎo)致客戶端在不通的時(shí)刻監(jiān)聽(tīng)到事件,由于 Zookeeper 本身提供了 ordering guarantee眼刃,即客戶端監(jiān)聽(tīng)事件后绕辖,才會(huì)感知它所監(jiān)視 znode發(fā)生了變化。
所以我們使用 Zookeeper 不能期望能夠監(jiān)控到節(jié)點(diǎn)每次的變化擂红。
(5)注冊(cè) watcher getData仪际、exists、getChildren
(6)觸發(fā) watcher create昵骤、delete树碱、setData
(7)
當(dāng)一個(gè)客戶端連接到一個(gè)新的服務(wù)器上時(shí),watch 將會(huì)被以任意會(huì)話事件觸發(fā)变秦。
當(dāng)與一個(gè)服務(wù)器失去連接的時(shí)候赴恨,是無(wú)法接收到 watch 的。
而當(dāng) client 重新連接時(shí)伴栓,如果需要的話,所有先前注冊(cè)過(guò)的 watch雨饺,都會(huì)被重新注冊(cè)钳垮。通常這是完全透明的。
只有在一個(gè)特殊情況下额港,watch 可能會(huì)丟失:對(duì)于一個(gè)未創(chuàng)建的 znode的 exist watch饺窿,如果在客戶端斷開(kāi)連接期間被創(chuàng)建了,并且隨后在客戶端連接上之前又刪除了移斩,這種情況下肚医,這個(gè) watch 事件可能會(huì)被丟失。
7. 客戶端注冊(cè) Watcher 實(shí)現(xiàn)
(1)調(diào)用 getData()/getChildren()/exist()三個(gè) API向瓷,傳入 Watcher 對(duì)象
(2)標(biāo)記請(qǐng)求 request肠套,封裝 Watcher 到 WatchRegistration
(3)封裝成 Packet 對(duì)象,發(fā)服務(wù)端發(fā)送 request
(4)收到服務(wù)端響應(yīng)后猖任,將 Watcher 注冊(cè)到 ZKWatcherManager 中進(jìn)行管理
(5)請(qǐng)求返回你稚,完成注冊(cè)。
8. 服務(wù)端處理 Watcher 實(shí)現(xiàn)
(1)服務(wù)端接收 Watcher 并存儲(chǔ)
接收到客戶端請(qǐng)求朱躺,處理請(qǐng)求判斷是否需要注冊(cè) Watcher刁赖,需要的話將數(shù)據(jù)節(jié)點(diǎn)的節(jié)點(diǎn)路徑和 ServerCnxn(ServerCnxn 代表一個(gè)客戶端和服務(wù)端的連接,實(shí)現(xiàn)了 Watcher 的 process 接口长搀,此時(shí)可以看成一個(gè) Watcher 對(duì)象)存儲(chǔ)在WatcherManager 的 WatchTable 和 watch2Paths 中去宇弛。
(2)Watcher 觸發(fā)
以服務(wù)端接收到 setData() 事務(wù)請(qǐng)求觸發(fā) NodeDataChanged 事件為例:
2.1 封裝 WatchedEvent
將通知狀態(tài)(SyncConnected)、事件類型(NodeDataChanged)以及節(jié)點(diǎn)路徑封裝成一個(gè) WatchedEvent 對(duì)象
2.2 查詢 Watcher
從 WatchTable 中根據(jù)節(jié)點(diǎn)路徑查找 Watcher
2.3 沒(méi)找到源请;說(shuō)明沒(méi)有客戶端在該數(shù)據(jù)節(jié)點(diǎn)上注冊(cè)過(guò) Watcher
2.4 找到枪芒;提取并從 WatchTable 和 Watch2Paths 中刪除對(duì)應(yīng) Watcher(從這里可以看出 Watcher 在服務(wù)端是一次性的彻况,觸發(fā)一次就失效了)
(3)調(diào)用 process 方法來(lái)觸發(fā) Watcher
這里 process 主要就是通過(guò) ServerCnxn 對(duì)應(yīng)的 TCP 連接發(fā)送 Watcher 事件通知。
9. 客戶端回調(diào) Watcher
客戶端 SendThread 線程接收事件通知病苗,交由 EventThread 線程回調(diào) Watcher疗垛。
客戶端的 Watcher 機(jī)制同樣是一次性的,一旦被觸發(fā)后硫朦,該 Watcher 就失效了贷腕。
10. ACL 權(quán)限控制機(jī)制
UGO(User/Group/Others)
目前在 Linux/Unix 文件系統(tǒng)中使用,也是使用最廣泛的權(quán)限控制方式咬展。是一種粗粒度的文件系統(tǒng)權(quán)限控制模式泽裳。
ACL(Access Control List)訪問(wèn)控制列表
包括三個(gè)方面:
權(quán)限模式(Scheme)
(1)IP:從 IP 地址粒度進(jìn)行權(quán)限控制
(2)Digest:最常用,用類似于 username:password 的權(quán)限標(biāo)識(shí)來(lái)進(jìn)行權(quán)限配置破婆,便于區(qū)分不同應(yīng)用來(lái)進(jìn)行權(quán)限控制
(3)World:最開(kāi)放的權(quán)限控制方式涮总,是一種特殊的 digest 模式,只有一個(gè)權(quán)限標(biāo)識(shí)“world:anyone”
(4)Super:超級(jí)用戶
授權(quán)對(duì)象
授權(quán)對(duì)象指的是權(quán)限賦予的用戶或一個(gè)指定實(shí)體祷舀,例如 IP 地址或是機(jī)器燈瀑梗。
權(quán)限 Permission
(1)CREATE:數(shù)據(jù)節(jié)點(diǎn)創(chuàng)建權(quán)限,允許授權(quán)對(duì)象在該 Znode 下創(chuàng)建子節(jié)點(diǎn)
(2)DELETE:子節(jié)點(diǎn)刪除權(quán)限裳扯,允許授權(quán)對(duì)象刪除該數(shù)據(jù)節(jié)點(diǎn)的子節(jié)點(diǎn)
(3)READ:數(shù)據(jù)節(jié)點(diǎn)的讀取權(quán)限抛丽,允許授權(quán)對(duì)象訪問(wèn)該數(shù)據(jù)節(jié)點(diǎn)并讀取其數(shù)據(jù)內(nèi)容或子節(jié)點(diǎn)列表等
(4)WRITE:數(shù)據(jù)節(jié)點(diǎn)更新權(quán)限,允許授權(quán)對(duì)象對(duì)該數(shù)據(jù)節(jié)點(diǎn)進(jìn)行更新操作
(5)ADMIN:數(shù)據(jù)節(jié)點(diǎn)管理權(quán)限饰豺,允許授權(quán)對(duì)象對(duì)該數(shù)據(jù)節(jié)點(diǎn)進(jìn)行 ACL 相關(guān)設(shè)置操作
11. Chroot 特性
3.2.0 版本后亿鲜,添加了 Chroot 特性,該特性允許每個(gè)客戶端為自己設(shè)置一個(gè)命名空間冤吨。
如果一個(gè)客戶端設(shè)置了 Chroot蒿柳,那么該客戶端對(duì)服務(wù)器的任何操作,都將會(huì)被限制在其自己的命名空間下漩蟆。
通過(guò)設(shè)置 Chroot垒探,能夠?qū)⒁粋€(gè)客戶端應(yīng)用于 Zookeeper 服務(wù)端的一顆子樹(shù)相對(duì)應(yīng),在那些多個(gè)應(yīng)用公用一個(gè) Zookeeper 進(jìn)群的場(chǎng)景下爆安,對(duì)實(shí)現(xiàn)不同應(yīng)用間的相互隔離非常有幫助叛复。
12. 會(huì)話管理
分桶策略:將類似的會(huì)話放在同一區(qū)塊中進(jìn)行管理,以便于 Zookeeper 對(duì)會(huì)話進(jìn)行不同區(qū)塊的隔離處理以及同一區(qū)塊的統(tǒng)一處理扔仓。
分配原則:每個(gè)會(huì)話的“下次超時(shí)時(shí)間點(diǎn)”(ExpirationTime)
計(jì)算公式:
ExpirationTime_ = currentTime + sessionTimeout
ExpirationTime = (ExpirationTime_ / ExpirationInrerval + 1) *
ExpirationInterval , ExpirationInterval 是指 Zookeeper 會(huì)話超時(shí)檢查時(shí)間間隔褐奥,默認(rèn) tickTime
13. 服務(wù)器角色
Leader
(1)事務(wù)請(qǐng)求的唯一調(diào)度和處理者,保證集群事務(wù)處理的順序性
(2)集群內(nèi)部各服務(wù)的調(diào)度者
Follower
(1)處理客戶端的非事務(wù)請(qǐng)求翘簇,轉(zhuǎn)發(fā)事務(wù)請(qǐng)求給 Leader 服務(wù)器
(2)參與事務(wù)請(qǐng)求 Proposal 的投票
(3)參與 Leader 選舉投票
Observer
(1)3.0 版本以后引入的一個(gè)服務(wù)器角色撬码,在不影響集群事務(wù)處理能力的基礎(chǔ)上提升集群的非事務(wù)處理能力
(2)處理客戶端的非事務(wù)請(qǐng)求,轉(zhuǎn)發(fā)事務(wù)請(qǐng)求給 Leader 服務(wù)器
(3)不參與任何形式的投票
14. Zookeeper 下 Server 工作狀態(tài)
服務(wù)器具有四種狀態(tài)版保,分別是 LOOKING呜笑、FOLLOWING夫否、LEADING、OBSERVING叫胁。
(1)LOOKING:尋 找 Leader 狀態(tài)凰慈。當(dāng)服務(wù)器處于該狀態(tài)時(shí),它會(huì)認(rèn)為當(dāng)前集群中沒(méi)有 Leader驼鹅,因此需要進(jìn)入 Leader 選舉狀態(tài)微谓。
(2)FOLLOWING:跟隨者狀態(tài)。表明當(dāng)前服務(wù)器角色是 Follower输钩。
(3)LEADING:領(lǐng)導(dǎo)者狀態(tài)豺型。表明當(dāng)前服務(wù)器角色是 Leader。
(4)OBSERVING:觀察者狀態(tài)买乃。表明當(dāng)前服務(wù)器角色是 Observer姻氨。
15. 數(shù)據(jù)同步
整個(gè)集群完成 Leader 選舉之后,Learner(Follower 和 Observer 的統(tǒng)稱)回向Leader 服務(wù)器進(jìn)行注冊(cè)剪验。當(dāng) Learner 服務(wù)器想 Leader 服務(wù)器完成注冊(cè)后肴焊,進(jìn)入數(shù)據(jù)同步環(huán)節(jié)。
數(shù)據(jù)同步流程:(均以消息傳遞的方式進(jìn)行)
- Learner 向 Learder 注冊(cè)
- 數(shù)據(jù)同步
- 同步確認(rèn)
Zookeeper 的數(shù)據(jù)同步通常分為四類:
(1)直接差異化同步(DIFF 同步)
(2)先回滾再差異化同步(TRUNC+DIFF 同步)
(3)僅回滾同步(TRUNC 同步)
(4)全量同步(SNAP 同步)
在進(jìn)行數(shù)據(jù)同步前功戚,Leader 服務(wù)器會(huì)完成數(shù)據(jù)同步初始化:
peerLastZxid:
· 從 learner 服務(wù)器注冊(cè)時(shí)發(fā)送的 ACKEPOCH 消息中提取 lastZxid(該Learner 服務(wù)器最后處理的 ZXID)
minCommittedLog:
· Leader 服務(wù)器 Proposal 緩存隊(duì)列 committedLog 中最小 ZXIDmaxCommittedLog:
· Leader 服務(wù)器 Proposal 緩存隊(duì)列 committedLog 中最大 ZXID直接差異化同步(DIFF 同步)
· 場(chǎng)景:peerLastZxid 介于 minCommittedLog 和 maxCommittedLog之間先回滾再差異化同步(TRUNC+DIFF 同步)
· 場(chǎng)景:當(dāng)新的 Leader 服務(wù)器發(fā)現(xiàn)某個(gè) Learner 服務(wù)器包含了一條自己沒(méi)有的事務(wù)記錄抖韩,那么就需要讓該 Learner 服務(wù)器進(jìn)行事務(wù)回滾--回滾到 Leader服務(wù)器上存在的,同時(shí)也是最接近于 peerLastZxid 的 ZXID僅回滾同步(TRUNC 同步)
· 場(chǎng)景:peerLastZxid 大于 maxCommittedLog
全量同步(SNAP 同步)
· 場(chǎng)景一:peerLastZxid 小于 minCommittedLog
· 場(chǎng)景二:Leader 服務(wù)器上沒(méi)有 Proposal 緩存隊(duì)列且 peerLastZxid 不等于 lastProcessZxid
16. zookeeper 是如何保證事務(wù)的順序一致性的疫铜?
zookeeper 采用了全局遞增的事務(wù) Id 來(lái)標(biāo)識(shí),所有的 proposal(提議)都在被提出的時(shí)候加上了 zxid双谆,zxid 實(shí)際上是一個(gè) 64 位的數(shù)字壳咕,高 32 位是 epoch( 時(shí)期; 紀(jì)元; 世; 新時(shí)代)用來(lái)標(biāo)識(shí) leader 周期,如果有新的 leader 產(chǎn)生出來(lái)顽馋,epoch會(huì)自增谓厘,低 32 位用來(lái)遞增計(jì)數(shù)。
當(dāng)新產(chǎn)生 proposal 的時(shí)候寸谜,會(huì)依據(jù)數(shù)據(jù)庫(kù)的兩階段過(guò)程竟稳,首先會(huì)向其他的 server 發(fā)出事務(wù)執(zhí)行請(qǐng)求,如果超過(guò)半數(shù)的機(jī)器都能執(zhí)行并且能夠成功熊痴,那么就會(huì)開(kāi)始執(zhí)行他爸。
17. 分布式集群中為什么會(huì)有 Master?
在分布式環(huán)境中果善,有些業(yè)務(wù)邏輯只需要集群中的某一臺(tái)機(jī)器進(jìn)行執(zhí)行诊笤,其他的機(jī)器可以共享這個(gè)結(jié)果,這樣可以大大減少重復(fù)計(jì)算巾陕,提高性能讨跟,于是就需要進(jìn)行l(wèi)eader 選舉纪他。
18. zk 節(jié)點(diǎn)宕機(jī)如何處理?
Zookeeper 本身也是集群晾匠,推薦配置不少于 3 個(gè)服務(wù)器茶袒。Zookeeper 自身也要保證當(dāng)一個(gè)節(jié)點(diǎn)宕機(jī)時(shí),其他節(jié)點(diǎn)會(huì)繼續(xù)提供服務(wù)凉馆。
如果是一個(gè) Follower 宕機(jī)薪寓,還有 2 臺(tái)服務(wù)器提供訪問(wèn),因?yàn)?Zookeeper 上的數(shù)據(jù)是有多個(gè)副本的句喜,數(shù)據(jù)并不會(huì)丟失预愤;
如果是一個(gè) Leader 宕機(jī),Zookeeper 會(huì)選舉出新的 Leader咳胃。
ZK 集群的機(jī)制是只要超過(guò)半數(shù)的節(jié)點(diǎn)正常植康,集群就能正常提供服務(wù)。只有在 ZK節(jié)點(diǎn)掛得太多展懈,只剩一半或不到一半節(jié)點(diǎn)能工作销睁,集群才失效。
所以
3 個(gè)節(jié)點(diǎn)的 cluster 可以掛掉 1 個(gè)節(jié)點(diǎn)(leader 可以得到 2 票>1.5)
2 個(gè)節(jié)點(diǎn)的 cluster 就不能掛掉任何 1 個(gè)節(jié)點(diǎn)了(leader 可以得到 1 票<=1)
19. zookeeper 負(fù)載均衡和 nginx 負(fù)載均衡區(qū)別
zk 的負(fù)載均衡是可以調(diào)控存崖,nginx 只是能調(diào)權(quán)重冻记,其他需要可控的都需要自己寫插件;
但是 nginx 的吞吐量比 zk 大很多来惧,應(yīng)該說(shuō)按業(yè)務(wù)選擇用哪種方式冗栗。
20. Zookeeper 有哪幾種幾種部署模式?
部署模式:?jiǎn)螜C(jī)模式供搀、偽集群模式隅居、集群模式。
21. 集群最少要幾臺(tái)機(jī)器葛虐,集群規(guī)則是怎樣的?
集群規(guī)則為 2N+1 臺(tái)胎源,N>0,即 3 臺(tái)屿脐。
22. 集群支持動(dòng)態(tài)添加機(jī)器嗎涕蚤?
其實(shí)就是水平擴(kuò)容了,Zookeeper 在這方面不太好的诵。
兩種方式:
全部重啟:關(guān)閉所有 Zookeeper 服務(wù)万栅,修改配置之后啟動(dòng)。不影響之前客戶端的會(huì)話西疤。
逐個(gè)重啟:在過(guò)半存活即可用的原則下申钩,一臺(tái)機(jī)器重啟不影響整個(gè)集群對(duì)外提供服務(wù)。這是比較常用的方式瘪阁。
3.5 版本開(kāi)始支持動(dòng)態(tài)擴(kuò)容撒遣。
23. Zookeeper 對(duì)節(jié)點(diǎn)的 watch 監(jiān)聽(tīng)通知是永久的嗎邮偎?為什么?
不是。
官方聲明:一個(gè) Watch 事件是一個(gè)一次性的觸發(fā)器义黎,當(dāng)被設(shè)置了 Watch的數(shù)據(jù)發(fā)生了改變的時(shí)候禾进,則服務(wù)器將這個(gè)改變發(fā)送給設(shè)置了 Watch 的客戶端,以便通知它們廉涕。
為什么不是永久的泻云,舉個(gè)例子,如果服務(wù)端變動(dòng)頻繁狐蜕,而監(jiān)聽(tīng)的客戶端很多情況下宠纯,每次變動(dòng)都要通知到所有的客戶端,給網(wǎng)絡(luò)和服務(wù)器造成很大壓力层释。
一般是客戶端執(zhí)行 getData(“/節(jié)點(diǎn) A”,true)婆瓜,如果節(jié)點(diǎn) A 發(fā)生了變更或刪除,客戶端會(huì)得到它的 watch 事件贡羔,但是在之后節(jié)點(diǎn) A 又發(fā)生了變更廉白,而客戶端又沒(méi)有設(shè)置 watch 事件,就不再給客戶端發(fā)送乖寒。
在實(shí)際應(yīng)用中猴蹂,很多情況下,我們的客戶端不需要知道服務(wù)端的每一次變動(dòng)楣嘁,我只要最新的數(shù)據(jù)即可磅轻。
24. Zookeeper 的 java 客戶端都有哪些?
java 客戶端:zk 自帶的 zkclient 及 Apache 開(kāi)源的 Curator逐虚。
25. chubby 是什么瓢省,和 zookeeper 比你怎么看?
chubby 是 google 的痊班,完全實(shí)現(xiàn) paxos 算法,不開(kāi)源摹量。
zookeeper 是 chubby的開(kāi)源實(shí)現(xiàn)涤伐,使用 zab 協(xié)議,paxos 算法的變種缨称。
26. zookeeper 常用的命令
ZooKeeper服務(wù)命令:
在準(zhǔn)備好相應(yīng)的配置之后凝果,可以直接通過(guò)zkServer.sh 這個(gè)腳本進(jìn)行服務(wù)的相關(guān)操作
1. 啟動(dòng)ZK服務(wù): ./zkServer.sh start
2. 查看ZK服務(wù)狀態(tài): ./zkServer.sh status
3. 停止ZK服務(wù): ./zkServer.sh stop
4. 重啟ZK服務(wù): ./zkServer.sh restart
5.連接ZK服務(wù): ./zkCli.sh -server ip:port
zk客戶端命令
ZooKeeper命令行工具類似于Linux的shell環(huán)境,不過(guò)功能肯定不及shell啦睦尽,但是使用它我們可以簡(jiǎn)單的對(duì)ZooKeeper進(jìn)行訪問(wèn)器净,數(shù)據(jù)創(chuàng)建,數(shù)據(jù)修改等操作. 使用 zkCli.sh -server 127.0.0.1:2181 連接到 ZooKeeper 服務(wù)当凡,連接成功后山害,系統(tǒng)會(huì)輸出 ZooKeeper 的相關(guān)環(huán)境以及配置信息纠俭。
1. 顯示根目錄下、文件: ls / 使用 ls 命令來(lái)查看當(dāng)前 ZooKeeper 中所包含的內(nèi)容
2. 創(chuàng)建文件浪慌,并設(shè)置初始內(nèi)容: create /zk "test" 創(chuàng)建一個(gè)新的 znode節(jié)點(diǎn)“ zk ”以及與它關(guān)聯(lián)的字符串
3. 獲取文件內(nèi)容: get /zk 確認(rèn) znode 是否包含我們所創(chuàng)建的字符串
4. 修改文件內(nèi)容: set /zk "zkbak" 對(duì) zk 所關(guān)聯(lián)的字符串進(jìn)行設(shè)置
5. 刪除文件:
delete /zk # 此命令不可以刪除有子節(jié)點(diǎn)的節(jié)點(diǎn)
rmr /zk# 該命令可以刪除有子節(jié)點(diǎn)的節(jié)點(diǎn)
6. 退出客戶端: quit
7. 幫助命令: help
授權(quán)
setAcl path acl
# 這是其中兩種授權(quán)方式的列子冤荆,其中rwadc分別代表讀、寫权纤、管理钓简、刪除、查詢五種方式,可選其中一種或者幾種
# 1.auth方式
addauth disgest username:password #(用戶名和密碼)
setAcl /auth auth:username:password:rwadc
# 2.digest方式
# 先將密碼明文加密,即先使用sha1汹想,再使用base64
echo -n test:test | openssl dgst -binary -sha1 | openssl base64
# 將生成的密文設(shè)為密碼
setAcl /path digest:用戶名:密碼密文:權(quán)限
# 3.訪問(wèn)外邓,兩種方式都是這樣
addauth digest 用戶名:密碼明文
get path
檢查權(quán)限
getAcl path
ZooKeeper 常用四字命令:
ZooKeeper 支持某些特定的四字命令字母與其的交互。它們大多是查詢命令古掏,用來(lái)獲取 ZooKeeper 服務(wù)的當(dāng)前狀態(tài)及相關(guān)信息损话。用戶在客戶端可以通過(guò) telnet 或 nc 向 ZooKeeper 提交相應(yīng)的命令
1. 可以通過(guò)命令:echo stat|nc 127.0.0.1 2181 來(lái)查看哪個(gè)節(jié)點(diǎn)被選擇作為follower或者leader
2. 使用echo ruok|nc 127.0.0.1 2181 測(cè)試是否啟動(dòng)了該Server,若回復(fù)imok表示已經(jīng)啟動(dòng)冗茸。
3. echo dump| nc 127.0.0.1 2181 ,列出未經(jīng)處理的會(huì)話和臨時(shí)節(jié)點(diǎn)席镀。
4. echo kill | nc 127.0.0.1 2181 ,關(guān)掉server
5. echo conf | nc 127.0.0.1 2181 ,輸出相關(guān)服務(wù)配置的詳細(xì)信息。
6. echo cons | nc 127.0.0.1 2181 ,列出所有連接到服務(wù)器的客戶端的完全的連接 / 會(huì)話的詳細(xì)信息夏漱。
7. echo envi |nc 127.0.0.1 2181 ,輸出關(guān)于服務(wù)環(huán)境的詳細(xì)信息(區(qū)別于 conf 命令)豪诲。
8. echo reqs | nc 127.0.0.1 2181 ,列出未經(jīng)處理的請(qǐng)求。
9. echo wchs | nc 127.0.0.1 2181 ,列出服務(wù)器 watch 的詳細(xì)信息挂绰。
10. echo wchc | nc 127.0.0.1 2181 ,通過(guò) session 列出服務(wù)器 watch 的詳細(xì)信息屎篱,它的輸出是一個(gè)與 watch 相關(guān)的會(huì)話的列表。
11. echo wchp | nc 127.0.0.1 2181 ,通過(guò)路徑列出服務(wù)器 watch 的詳細(xì)信息葵蒂。它輸出一個(gè)與 session 相關(guān)的路徑交播。
27. ZAB 和 Paxos 算法的聯(lián)系與區(qū)別?
相同點(diǎn):
(1)兩者都存在一個(gè)類似于 Leader 進(jìn)程的角色践付,由其負(fù)責(zé)協(xié)調(diào)多個(gè) Follower 進(jìn)程的運(yùn)行
(2)Leader 進(jìn)程都會(huì)等待超過(guò)半數(shù)的 Follower 做出正確的反饋后秦士,才會(huì)將一個(gè)提案進(jìn)行提交
(3)ZAB 協(xié)議中,每個(gè) Proposal 中都包含一個(gè) epoch 值來(lái)代表當(dāng)前的 Leader周期永高,Paxos 中名字為 Ballot
不同點(diǎn):
ZAB 用來(lái)構(gòu)建高可用的分布式數(shù)據(jù)主備系統(tǒng)(Zookeeper)隧土,Paxos 是用來(lái)構(gòu)建分布式一致性狀態(tài)機(jī)系統(tǒng)。
28. Zookeeper 的典型應(yīng)用場(chǎng)景
Zookeeper 是一個(gè)典型的發(fā)布/訂閱模式的分布式數(shù)據(jù)管理與協(xié)調(diào)框架命爬,開(kāi)發(fā)人員可以使用它來(lái)進(jìn)行分布式數(shù)據(jù)的發(fā)布和訂閱曹傀。
通過(guò)對(duì) Zookeeper 中豐富的數(shù)據(jù)節(jié)點(diǎn)進(jìn)行交叉使用,配合 Watcher 事件通知機(jī)制饲宛,可以非常方便的構(gòu)建一系列分布式應(yīng)用中年都會(huì)涉及的核心功能皆愉,如:
(1)數(shù)據(jù)發(fā)布/訂閱
(2)負(fù)載均衡
(3)命名服務(wù)
(4)分布式協(xié)調(diào)/通知
(5)集群管理
(6)Master 選舉
(7)分布式鎖
(8)分布式隊(duì)列
數(shù)據(jù)發(fā)布/訂閱
介紹
數(shù)據(jù)發(fā)布/訂閱系統(tǒng),即所謂的配置中心,顧名思義就是發(fā)布者發(fā)布數(shù)據(jù)供訂閱者進(jìn)行數(shù)據(jù)訂閱幕庐。
目的
動(dòng)態(tài)獲取數(shù)據(jù)(配置信息)
實(shí)現(xiàn)數(shù)據(jù)(配置信息)的集中式管理和數(shù)據(jù)的動(dòng)態(tài)更新
設(shè)計(jì)模式
Push 模式
Pull 模式
數(shù)據(jù)(配置信息)特性
(1)數(shù)據(jù)量通常比較小
(2)數(shù)據(jù)內(nèi)容在運(yùn)行時(shí)會(huì)發(fā)生動(dòng)態(tài)更新
(3)集群中各機(jī)器共享久锥,配置一致
如:機(jī)器列表信息、運(yùn)行時(shí)開(kāi)關(guān)配置翔脱、數(shù)據(jù)庫(kù)配置信息等
基于 Zookeeper 的實(shí)現(xiàn)方式
· 數(shù)據(jù)存儲(chǔ):將數(shù)據(jù)(配置信息)存儲(chǔ)到 Zookeeper 上的一個(gè)數(shù)據(jù)節(jié)點(diǎn)
· 數(shù)據(jù)獲扰埂:應(yīng)用在啟動(dòng)初始化節(jié)點(diǎn)從 Zookeeper 數(shù)據(jù)節(jié)點(diǎn)讀取數(shù)據(jù),并在該節(jié)點(diǎn)上注冊(cè)一個(gè)數(shù)據(jù)變更 Watcher
· 數(shù)據(jù)變更:當(dāng)變更數(shù)據(jù)時(shí)届吁,更新 Zookeeper 對(duì)應(yīng)節(jié)點(diǎn)數(shù)據(jù)错妖,Zookeeper會(huì)將數(shù)據(jù)變更通知發(fā)到各客戶端,客戶端接到通知后重新讀取變更后的數(shù)據(jù)即可疚沐。
負(fù)載均衡
主要是三點(diǎn):負(fù)載均衡算法暂氯,健康檢查和會(huì)話保持
Zookeeper中,服務(wù)提供者在啟動(dòng)時(shí)亮蛔,將其提供的服務(wù)名稱痴施、服務(wù)器地址、以節(jié)點(diǎn)的形式注冊(cè)到服務(wù)配置中心究流,服務(wù)消費(fèi)者通過(guò)服務(wù)配置中心來(lái)獲得需要調(diào)用的服務(wù)名稱節(jié)點(diǎn)下的機(jī)器列表節(jié)點(diǎn)辣吃。
通過(guò)負(fù)載均衡算法,選取其中一臺(tái)服務(wù)器進(jìn)行調(diào)用芬探。當(dāng)服務(wù)器宕機(jī)或者下線時(shí)神得,由于znode非持久的特性,相應(yīng)的機(jī)器可以動(dòng)態(tài)地從服務(wù)配置中心里面移除偷仿,并觸發(fā)服務(wù)消費(fèi)者的watcher哩簿。
在這個(gè)過(guò)程中,服務(wù)消費(fèi)者只有在第一次調(diào)用服務(wù)時(shí)需要查詢服務(wù)配置中心酝静,然后將查詢到的服務(wù)信息緩存到本地节榜,后面的調(diào)用直接使用本地緩存的服務(wù)地址列表信息,而不需要重新發(fā)起請(qǐng)求到服務(wù)配置中心去獲取相應(yīng)的服務(wù)地址列表别智,直到服務(wù)的地址列表有變更(機(jī)器上線或者下線)宗苍,變更行為會(huì)觸發(fā)服務(wù)消費(fèi)者注冊(cè)的相應(yīng)的watcher進(jìn)行服務(wù)地址的重新查詢。
這種無(wú)中心化的結(jié)構(gòu)薄榛,使得服務(wù)消費(fèi)者在服務(wù)信息沒(méi)有變更時(shí)讳窟,幾乎不依賴配置中心,解決了之前負(fù)載均衡設(shè)備所導(dǎo)致的單點(diǎn)故障的問(wèn)題蛇数,并且大大降低了服務(wù)配置中心的壓力。
zk 的命名服務(wù)
命名服務(wù)是指通過(guò)指定的名字來(lái)獲取資源或者服務(wù)的地址是越,利用 zk 創(chuàng)建一個(gè)全局的路徑耳舅,這個(gè)路徑就可以作為一個(gè)名字,指向集群中的集群,提供的服務(wù)的地址浦徊,或者一個(gè)遠(yuǎn)程的對(duì)象等等馏予。
分布式通知和協(xié)調(diào)
對(duì)于系統(tǒng)調(diào)度來(lái)說(shuō):操作人員發(fā)送通知實(shí)際是通過(guò)控制臺(tái)改變某個(gè)節(jié)點(diǎn)的狀態(tài),然后 zk 將這些變化發(fā)送給注冊(cè)了這個(gè)節(jié)點(diǎn)的 watcher 的所有客戶端盔性。
對(duì)于執(zhí)行情況匯報(bào):每個(gè)工作進(jìn)程都在某個(gè)目錄下創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn)霞丧。并攜帶工作的進(jìn)度數(shù)據(jù),這樣匯總的進(jìn)程可以監(jiān)控目錄子節(jié)點(diǎn)的變化獲得工作進(jìn)度的實(shí)時(shí)的全局情況冕香。
zk 的配置管理(文件系統(tǒng)蛹尝、通知機(jī)制)
程序分布式的部署在不同的機(jī)器上,將程序的配置信息放在 zk 的 znode 下悉尾,當(dāng)有配置發(fā)生改變時(shí)突那,也就是 znode 發(fā)生變化時(shí),可以通過(guò)改變 zk 中某個(gè)目錄節(jié)點(diǎn)的內(nèi)容构眯,利用 watcher 通知給各個(gè)客戶端愕难,從而更改配置。
Zookeeper 集群管理(文件系統(tǒng)惫霸、通知機(jī)制)
所謂集群管理無(wú)在乎兩點(diǎn):是否有機(jī)器退出和加入猫缭、選舉 master。
對(duì)于第一點(diǎn)壹店,所有機(jī)器約定在父目錄下創(chuàng)建臨時(shí)目錄節(jié)點(diǎn)猜丹,然后監(jiān)聽(tīng)父目錄節(jié)點(diǎn)的子節(jié)點(diǎn)變化消息。
一旦有機(jī)器掛掉茫打,該機(jī)器與 zookeeper 的連接斷開(kāi)居触,其所創(chuàng)建的臨時(shí)目錄節(jié)點(diǎn)被刪除,所有其他機(jī)器都收到通知:某個(gè)兄弟目錄被刪除老赤,于是轮洋,所有人都知道:它上船了。
新機(jī)器加入也是類似抬旺,所有機(jī)器收到通知:新兄弟目錄加入弊予,highcount 又有了.
對(duì)于第二點(diǎn),我們稍微改變一下开财,所有機(jī)器創(chuàng)建臨時(shí)順序編號(hào)目錄節(jié)點(diǎn)汉柒,每次選取編號(hào)最小的機(jī)器作為 master 就好。
Zookeeper 分布式鎖(文件系統(tǒng)责鳍、通知機(jī)制)
有了 zookeeper 的一致性文件系統(tǒng)碾褂,鎖的問(wèn)題變得容易。鎖服務(wù)可以分為兩類历葛,一個(gè)是保持獨(dú)占正塌,另一個(gè)是控制時(shí)序嘀略。
對(duì)于第一類,我們將 zookeeper 上的一個(gè) znode 看作是一把鎖乓诽,通過(guò) createznode的方式來(lái)實(shí)現(xiàn)帜羊。
所有客戶端都去創(chuàng)建 /distribute_lock 節(jié)點(diǎn),最終成功創(chuàng)建的那個(gè)客戶端也即擁有了這把鎖鸠天。
用完刪除掉自己創(chuàng)建的 distribute_lock 節(jié)點(diǎn)就釋放出鎖讼育。
對(duì)于第二類, /distribute_lock 已經(jīng)預(yù)先存在稠集,所有客戶端在它下面創(chuàng)建臨時(shí)順序編號(hào)目錄節(jié)點(diǎn)奶段,和選 master 一樣,編號(hào)最小的獲得鎖巍杈,用完刪除忧饭,依次方便。
Zookeeper 隊(duì)列管理(文件系統(tǒng)筷畦、通知機(jī)制)
兩種類型的隊(duì)列:
(1)同步隊(duì)列词裤,當(dāng)一個(gè)隊(duì)列的成員都聚齊時(shí),這個(gè)隊(duì)列才可用鳖宾,否則一直等待所有成員到達(dá)吼砂。
(2)隊(duì)列按照 FIFO 方式進(jìn)行入隊(duì)和出隊(duì)操作。
第一類鼎文,在約定目錄下創(chuàng)建臨時(shí)目錄節(jié)點(diǎn)渔肩,監(jiān)聽(tīng)節(jié)點(diǎn)數(shù)目是否是我們要求的數(shù)目。
第二類拇惋,和分布式鎖服務(wù)中的控制時(shí)序場(chǎng)景基本原理一致周偎,入列有編號(hào),出列按編號(hào)撑帖。
在特定的目錄下創(chuàng)建 PERSISTENT_SEQUENTIAL 節(jié)點(diǎn)蓉坎,創(chuàng)建成功時(shí)Watcher 通知等待的隊(duì)列,隊(duì)列刪除序列號(hào)最小的節(jié)點(diǎn)用以消費(fèi)胡嘿。
此場(chǎng)景下Zookeeper 的 znode 用于消息存儲(chǔ)蛉艾,znode 存儲(chǔ)的數(shù)據(jù)就是消息隊(duì)列中的消息內(nèi)容,SEQUENTIAL 序列號(hào)就是消息的編號(hào)衷敌,按序取出即可勿侯。
由于創(chuàng)建的節(jié)點(diǎn)是持久化的,所以不必?fù)?dān)心隊(duì)列消息的丟失問(wèn)題缴罗。
作者:程序員追風(fēng)