ZooKeeper原理及使用
ZooKeeper是Hadoop Ecosystem中非常重要的組件,它的主要功能是為分布式系統(tǒng)提供一致性協(xié)調(diào)(Coordination)服務(wù),與之對(duì)應(yīng)的Google的類似服務(wù)叫Chubby。今天這篇文章分為三個(gè)部分來(lái)介紹ZooKeeper,第一部分介紹ZooKeeper的基本原理,,第二部分介紹ZooKeeper提供的Client API的使用,第三部分介紹一些ZooKeeper典型的應(yīng)用場(chǎng)景。
ZooKeeper基本原理1. 數(shù)據(jù)模型
如上圖所示,ZooKeeper數(shù)據(jù)模型的結(jié)構(gòu)與Unix文件系統(tǒng)很類似,整體上可以看作是一棵樹(shù),每個(gè)節(jié)點(diǎn)稱做一個(gè)ZNode。每個(gè)ZNode都可以通過(guò)其路徑唯一標(biāo)識(shí),比如上圖中第三層的第一個(gè)ZNode, 它的路徑是/app1/c1。在每個(gè)ZNode上可存儲(chǔ)少量數(shù)據(jù)(默認(rèn)是1M, 可以通過(guò)配置修改, 通常不建議在ZNode上存儲(chǔ)大量的數(shù)據(jù)),這個(gè)特性非常有用,在后面的典型應(yīng)用場(chǎng)景中會(huì)介紹到。另外,每個(gè)ZNode上還存儲(chǔ)了其Acl信息,這里需要注意,雖說(shuō)ZNode的樹(shù)形結(jié)構(gòu)跟Unix文件系統(tǒng)很類似,但是其Acl與Unix文件系統(tǒng)是完全不同的,每個(gè)ZNode的Acl的獨(dú)立的,子結(jié)點(diǎn)不會(huì)繼承父結(jié)點(diǎn)的,關(guān)于ZooKeeper中的Acl可以參考之前寫(xiě)過(guò)的一篇文章《說(shuō)說(shuō)Zookeeper中的ACL》。
2.重要概念
2.1 ZNode
前文已介紹了ZNode, ZNode根據(jù)其本身的特性,可以分為下面兩類:
ZNode還有一個(gè)Sequential的特性,如果創(chuàng)建的時(shí)候指定的話,該ZNode的名字后面會(huì)自動(dòng)Append一個(gè)不斷增加的SequenceNo。
2.2 Session
Client與ZooKeeper之間的通信,需要?jiǎng)?chuàng)建一個(gè)Session,這個(gè)Session會(huì)有一個(gè)超時(shí)時(shí)間。因?yàn)閆ooKeeper集群會(huì)把Client的Session信息持久化,所以在Session沒(méi)超時(shí)之前,Client與ZooKeeper Server的連接可以在各個(gè)ZooKeeper Server之間透明地移動(dòng)。
在實(shí)際的應(yīng)用中,如果Client與Server之間的通信足夠頻繁,Session的維護(hù)就不需要其它額外的消息了。否則,ZooKeeper Client會(huì)每t/3 ms發(fā)一次心跳給Server,如果Client 2t/3 ms沒(méi)收到來(lái)自Server的心跳回應(yīng),就會(huì)換到一個(gè)新的ZooKeeper Server上。這里t是用戶配置的Session的超時(shí)時(shí)間。
2.3 Watcher
ZooKeeper支持一種Watch操作,Client可以在某個(gè)ZNode上設(shè)置一個(gè)Watcher,來(lái)Watch該ZNode上的變化。如果該ZNode上有相應(yīng)的變化,就會(huì)觸發(fā)這個(gè)Watcher,把相應(yīng)的事件通知給設(shè)置Watcher的Client。需要注意的是,ZooKeeper中的Watcher是一次性的,即觸發(fā)一次就會(huì)被取消,如果想繼續(xù)Watch的話,需要客戶端重新設(shè)置Watcher。這個(gè)跟epoll里的oneshot模式有點(diǎn)類似。
3. ZooKeeper特性
3.1 讀、寫(xiě)(更新)模式
在ZooKeeper集群中,讀可以從任意一個(gè)ZooKeeper Server讀,這一點(diǎn)是保證ZooKeeper比較好的讀性能的關(guān)鍵;寫(xiě)的請(qǐng)求會(huì)先Forwarder到Leader,然后由Leader來(lái)通過(guò)ZooKeeper中的原子廣播協(xié)議,將請(qǐng)求廣播給所有的Follower,Leader收到一半以上的寫(xiě)成功的Ack后,就認(rèn)為該寫(xiě)成功了,就會(huì)將該寫(xiě)進(jìn)行持久化,并告訴客戶端寫(xiě)成功了。
3.2 WAL和Snapshot
和大多數(shù)分布式系統(tǒng)一樣,ZooKeeper也有WAL(Write-Ahead-Log),對(duì)于每一個(gè)更新操作,ZooKeeper都會(huì)先寫(xiě)WAL, 然后再對(duì)內(nèi)存中的數(shù)據(jù)做更新,然后向Client通知更新結(jié)果。另外,ZooKeeper還會(huì)定期將內(nèi)存中的目錄樹(shù)進(jìn)行Snapshot,落地到磁盤(pán)上,這個(gè)跟HDFS中的FSImage是比較類似的。這么做的主要目的,一當(dāng)然是數(shù)據(jù)的持久化,二是加快重啟之后的恢復(fù)速度,如果全部通過(guò)Replay WAL的形式恢復(fù)的話,會(huì)比較慢。
3.3 FIFO
對(duì)于每一個(gè)ZooKeeper客戶端而言,所有的操作都是遵循FIFO順序的,這一特性是由下面兩個(gè)基本特性來(lái)保證的:一是ZooKeeper Client與Server之間的網(wǎng)絡(luò)通信是基于TCP,TCP保證了Client/Server之間傳輸包的順序;二是ZooKeeper Server執(zhí)行客戶端請(qǐng)求也是嚴(yán)格按照FIFO順序的。
3.4 Linearizability
在ZooKeeper中,所有的更新操作都有嚴(yán)格的偏序關(guān)系,更新操作都是串行執(zhí)行的,這一點(diǎn)是保證ZooKeeper功能正確性的關(guān)鍵。
ZooKeeper Client Library提供了豐富直觀的API供用戶程序使用,下面是一些常用的API:
ZooKeeper典型應(yīng)用場(chǎng)景1. 名字服務(wù)(NameService)
分布式應(yīng)用中,通常需要一套完備的命令機(jī)制,既能產(chǎn)生唯一的標(biāo)識(shí),又方便人識(shí)別和記憶。 我們知道,每個(gè)ZNode都可以由其路徑唯一標(biāo)識(shí),路徑本身也比較簡(jiǎn)潔直觀,另外ZNode上還可以存儲(chǔ)少量數(shù)據(jù),這些都是實(shí)現(xiàn)統(tǒng)一的NameService的基礎(chǔ)。下面以在HDFS中實(shí)現(xiàn)NameService為例,來(lái)說(shuō)明實(shí)現(xiàn)NameService的基本布驟:
2. 配置管理(Configuration Management)
在分布式系統(tǒng)中,常會(huì)遇到這樣的場(chǎng)景: 某個(gè)Job的很多個(gè)實(shí)例在運(yùn)行,它們?cè)谶\(yùn)行時(shí)大多數(shù)配置項(xiàng)是相同的,如果想要統(tǒng)一改某個(gè)配置,一個(gè)個(gè)實(shí)例去改,是比較低效,也是比較容易出錯(cuò)的方式。通過(guò)ZooKeeper可以很好的解決這樣的問(wèn)題,下面的基本的步驟:
3. 組員管理(Group Membership)
在典型的Master-Slave結(jié)構(gòu)的分布式系統(tǒng)中,Master需要作為“總管”來(lái)管理所有的Slave, 當(dāng)有Slave加入,或者有Slave宕機(jī),Master都需要感知到這個(gè)事情,然后作出對(duì)應(yīng)的調(diào)整,以便不影響整個(gè)集群對(duì)外提供服務(wù)。以HBase為例,HMaster管理了所有的RegionServer,當(dāng)有新的RegionServer加入的時(shí)候,HMaster需要分配一些Region到該RegionServer上去,讓其提供服務(wù);當(dāng)有RegionServer宕機(jī)時(shí),HMaster需要將該RegionServer之前服務(wù)的Region都重新分配到當(dāng)前正在提供服務(wù)的其它RegionServer上,以便不影響客戶端的正常訪問(wèn)。下面是這種場(chǎng)景下使用ZooKeeper的基本步驟:
4. 簡(jiǎn)單互斥鎖(Simple Lock)
我們知識(shí),在傳統(tǒng)的應(yīng)用程序中,線程、進(jìn)程的同步,都可以通過(guò)操作系統(tǒng)提供的機(jī)制來(lái)完成。但是在分布式系統(tǒng)中,多個(gè)進(jìn)程之間的同步,操作系統(tǒng)層面就無(wú)能為力了。這時(shí)候就需要像ZooKeeper這樣的分布式的協(xié)調(diào)(Coordination)服務(wù)來(lái)協(xié)助完成同步,下面是用ZooKeeper實(shí)現(xiàn)簡(jiǎn)單的互斥鎖的步驟,這個(gè)可以和線程間同步的mutex做類比來(lái)理解:
5. 互斥鎖(Simple Lock without Herd Effect)
上一節(jié)的例子中有一個(gè)問(wèn)題,每次搶鎖都會(huì)有大量的進(jìn)程去競(jìng)爭(zhēng),會(huì)造成羊群效應(yīng)(Herd Effect),為了解決這個(gè)問(wèn)題,我們可以通過(guò)下面的步驟來(lái)改進(jìn)上述過(guò)程:
這里需要補(bǔ)充一點(diǎn),通常在分布式系統(tǒng)中用ZooKeeper來(lái)做Leader Election(選主)就是通過(guò)上面的機(jī)制來(lái)實(shí)現(xiàn)的,這里的持鎖者就是當(dāng)前的“主”。
6. 讀寫(xiě)鎖(Read/Write Lock)
我們知道,讀寫(xiě)鎖跟互斥鎖相比不同的地方是,它分成了讀和寫(xiě)兩種模式,多個(gè)讀可以并發(fā)執(zhí)行,但寫(xiě)和讀、寫(xiě)都互斥,不能同時(shí)執(zhí)行行。利用ZooKeeper,在上面的基礎(chǔ)上,稍做修改也可以實(shí)現(xiàn)傳統(tǒng)的讀寫(xiě)鎖的語(yǔ)義,下面是基本的步驟:
7. 屏障(Barrier)
在分布式系統(tǒng)中,屏障是這樣一種語(yǔ)義: 客戶端需要等待多個(gè)進(jìn)程完成各自的任務(wù),然后才能繼續(xù)往前進(jìn)行下一步。下用是用ZooKeeper來(lái)實(shí)現(xiàn)屏障的基本步驟:
8. 雙屏障(Double Barrier)
雙屏障是這樣一種語(yǔ)義: 它可以用來(lái)同步一個(gè)任務(wù)的開(kāi)始和結(jié)束,當(dāng)有足夠多的進(jìn)程進(jìn)入屏障后,才開(kāi)始執(zhí)行任務(wù);當(dāng)所有的進(jìn)程都執(zhí)行完各自的任務(wù)后,屏障才撤銷。下面是用ZooKeeper來(lái)實(shí)現(xiàn)雙屏障的基本步驟:
相關(guān)日志
Zemanta
本文編號(hào):32332
本文鏈接:http://sikaile.net/wenshubaike/dxkc/32332.html