zookeeper基本原理及适用场景 转:http://blog.chinaunix.net/uid-26748613-id-4536290.html
1.1 zookeeper簡介
?????? Zookeeper?是?Hadoop?生態(tài)系統(tǒng)中的協同實現,是Hadoop集群管理的一個必不可少的模塊,它主要來控制集群中的數據,如它管理Hadoop集群中的NameNode,還有Hbase中Master Election、Server之間狀態(tài)同步等。Zookeeper?實際上是?Google?的?Chubby?一個開源的實現。Zookeeper?的配置中心實現更像一個文件系統(tǒng),文件系統(tǒng)中的所有文件形成一個樹狀結構。Zookeeper?維護著這樣的樹形層次結構,樹中的節(jié)點稱為?Znode,?每個?Znode?存儲的數據有小于?1m?的大小限制。zookeeper?對?Znode?提供了幾種類型:臨時?Znode、持久?Znode、順序?node?等幾種類型,用于不同的一致性需求。在?Znode?發(fā)生變化時,通過“觀察”(watch)機制可以讓客戶端得到通知。可以針對?Zookeeper?服務的“操作”來設置觀察,該服務的其他操作可以觸發(fā)觀察。Zookeeper?服務的“操作”包括一些對?Znode?添加修改獲取操作。Zookeeper?采用一種類似?Paxos?的算法實現領導者選舉,用于解決集群宕機的一致性和協同保障。總體上,Zookeeper?提供了一個分布式協同系統(tǒng),包括配置維護、名字服務、分布式同步、組服務等功能,并將相關操作接口提供給用戶。
1.2 zookeeper架構
?????? Zookeeper?從設計模式角度來看,是一個基于觀察者模式設計的分布式服務管理框架,它負責存儲和管理大家都關心的數據,然后接受觀察者的注冊,一旦這些數據的狀態(tài)發(fā)生變化,Zookeeper?就將負責通知已經在?Zookeeper?上注冊的那些觀察者做出相應的反應,從而實現集群中類似?Master/Slave?管理模式。
?Zookeeper數據結構的特點:
?? 每個子目錄項如?NameService?都被稱作為?Znode,這個?Znode?是被它所在的路徑唯一標識,如?Server1?這個?Znode?的標識為?/NameService/Server1;
???Znode?可以有子節(jié)點目錄,并且每個?Znode?可以存儲數據,注意?EPHEMERAL?類型的目錄節(jié)點不能有子節(jié)點目錄(因為它是臨時節(jié)點);
???Znode?是有版本的,每個?Znode?中存儲的數據可以有多個版本,也就是一個訪問路徑中可以存儲多份數據;
???Znode?可以是臨時節(jié)點,一旦創(chuàng)建這個?Znode?的客戶端與服務器失去聯系,這個?Znode?也將自動刪除,Zookeeper?的客戶端和服務器通信采用長連接方式,每個客戶端和服務器通過心跳來保持連接,這個連接狀態(tài)稱為?session,如果?Znode?是臨時節(jié)點,這個?session?失效,Znode?也就刪除了
???Znode?的目錄名可以自動編號,如?App1?已經存在,再創(chuàng)建的話,將會自動命名為?App2
???Znode?可以被監(jiān)控,包括這個目錄節(jié)點中存儲的數據的修改,子節(jié)點目錄的變化等,一旦變化可以通知設置監(jiān)控的客戶端,這個是?Zookeeper?的核心特性。
1.2 zookeeper使用場景
1.2.1統(tǒng)一命名服務(Name Service)
分布式應用中,通常需要有一套完整的命名規(guī)則,既能夠產生唯一的名稱又便于人識別和記住,通常情況下用樹形的名稱結構是一個理想的選擇,樹形的名稱結構是一個有層次的目錄結構,既對人友好又不會重復。Name Service?已經是?Zookeeper?內置的功能,你只要調用?Zookeeper?的?API?就能實現。如調用?create?接口就可以很容易創(chuàng)建一個目錄節(jié)點。
例如有一組服務器向客戶端提供某種服務,我們希望客戶端每次請求服務端都可以找到服務端集群中某一臺服務器,這樣服務端就可以向客戶端提供客戶端所需的服務。對于這種場景,我們的程序中一定有一份這組服務器的列表,每次客戶端請求時候,都是從這份列表里讀取這份服務器列表。那么這分列表顯然不能存儲在一臺單節(jié)點的服務器上,否則這個節(jié)點掛掉了,整個集群都會發(fā)生故障,我們希望這份列表時高可用的。高可用的解決方案是:這份列表是分布式存儲的,它是由存儲這份列表的服務器共同管理的,如果存儲列表里的某臺服務器壞掉了,其他服務器馬上可以替代壞掉的服務器,并且可以把壞掉的服務器從列表里刪除掉,讓故障服務器退出整個集群的運行,而這一切的操作又不會由故障的服務器來操作,而是集群里正常的服務器來完成。這是一種主動的分布式數據結構,能夠在外部情況發(fā)生變化時候主動修改數據項狀態(tài)的數據機構。Zookeeper框架提供了這種服務。這種服務名字就是:統(tǒng)一命名服務。
1.2.2配置管理(Configuration Management)
配置的管理在分布式應用環(huán)境中很常見,例如同一個應用系統(tǒng)需要多臺?PC Server?運行,但是它們運行的應用系統(tǒng)的某些配置項是相同的,如果要修改這些相同的配置項,那么就必須同時修改每臺運行這個應用系統(tǒng)的?PC Server,這樣非常麻煩而且容易出錯。像這樣的配置信息完全可以交給?Zookeeper?來管理,將配置信息保存在?Zookeeper?的某個目錄節(jié)點中,然后將所有需要修改的應用機器監(jiān)控配置信息的狀態(tài),一旦配置信息發(fā)生變化,每臺應用機器就會收到?Zookeeper?的通知,然后從?Zookeeper?獲取新的配置信息應用到系統(tǒng)中。zookeeper服務也會保證同步操作原子性(要么成功同步成功,要么失敗),確保每個服務器的配置文件都能被正確的更新。
1.2.3集群管理(Group Membership)
Zookeeper?能夠很容易的實現集群管理的功能,如有多臺?Server?組成一個服務集群,那么必須要一個master知道當前集群中每臺機器的服務狀態(tài),一旦有機器不能提供服務,集群中其它節(jié)點必須知道,從而做出調整重新分配服務策略。同樣當增加集群的服務能力時,就會增加一臺或多臺?Server,同樣也必須讓master知道。Zookeeper?不僅能夠幫你維護當前的集群中機器的服務狀態(tài),而且能夠幫你選出一個master,讓這個master來管理集群,這就是?Zookeeper?的另一個功能?Leader Election。
它們的實現方式都是在?Zookeeper?上創(chuàng)建一個?EPHEMERAL?類型的目錄節(jié)點,然后每個?Server?在它們創(chuàng)建目錄節(jié)點的父目錄節(jié)點上調用getChildren(String?path, boolean?watch)?方法并設置?watch?為?true,由于是?EPHEMERAL?目錄節(jié)點,當創(chuàng)建它的?Server?死去,這個目錄節(jié)點也隨之被刪除,所以?Children?將會變化,這時?getChildren上的?Watch?將會被調用,所以其它?Server?就知道已經有某臺?Server?死去了。新增?Server?也是同樣的原理。
Zookeeper?如何實現?Leader Election,也就是選出一個?Master Server。和前面的一樣每臺?Server?創(chuàng)建一個?EPHEMERAL?目錄節(jié)點,不同的是它還是一個?SEQUENTIAL?目錄節(jié)點,所以它是個?EPHEMERAL_SEQUENTIAL?目錄節(jié)點。之所以它是?EPHEMERAL_SEQUENTIAL?目錄節(jié)點,是因為我們可以給每臺?Server?編號,我們可以選擇當前是最小編號的?Server?為?Master,假如這個最小編號的?Server?死去,由于是?EPHEMERAL?節(jié)點,死去的?Server?對應的節(jié)點也被刪除,所以當前的節(jié)點列表中又出現一個最小編號的節(jié)點,我們就選擇這個節(jié)點為當前?Master。這樣就實現了動態(tài)選擇?Master,避免了傳統(tǒng)意義上單?Master?容易出現單點故障的問題。
1.2.4共享鎖(Locks)
共享鎖在同一個進程中很容易實現,但是在跨進程或者在不同?Server?之間就不好實現了。Zookeeper?卻很容易實現這個功能,實現方式也是需要獲得鎖的?Server?創(chuàng)建一個?EPHEMERAL_SEQUENTIAL?目錄節(jié)點,然后調用?getChildren方法獲取當前的目錄節(jié)點列表中最小的目錄節(jié)點是不是就是自己創(chuàng)建的目錄節(jié)點,如果正是自己創(chuàng)建的,那么它就獲得了這個鎖,如果不是那么它就調用?exists(String?path, boolean?watch)?方法并監(jiān)控?Zookeeper?上目錄節(jié)點列表的變化,一直到自己創(chuàng)建的節(jié)點是列表中最小編號的目錄節(jié)點,從而獲得鎖,釋放鎖很簡單,只要刪除前面它自己所創(chuàng)建的目錄節(jié)點就行了。
當分布式系統(tǒng)操作數據,例如:讀取數據、分析數據、最后修改數據。在分布式系統(tǒng)里這些操作可能會分散到集群里不同的節(jié)點上,那么這時候就存在數據操作過程中一致性的問題,如果不一致,我們將會得到一個錯誤的運算結果,在單一進程的程序里,一致性的問題很好解決,但是到了分布式系統(tǒng)就比較困難,因為分布式系統(tǒng)里不同服務器的運算都是在獨立的進程里,運算的中間結果和過程還要通過網絡進行傳遞,那么想做到數據操作一致性要困難的多。Zookeeper提供了一個鎖服務解決了這樣的問題,能讓我們在做分布式數據運算時候,保證數據操作的一致性。
1.2.5隊列管理
Zookeeper?可以處理兩種類型的隊列:
同步隊列:當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達,這種是同步隊列。
同步隊列用?Zookeeper?實現的實現思路如下:
創(chuàng)建一個父目錄?/synchronizing,每個成員都監(jiān)控標志(Set Watch)位目錄?/synchronizing/start?是否存在,然后每個成員都加入這個隊列,加入隊列的方式就是創(chuàng)建?/synchronizing/member_i?的臨時目錄節(jié)點,然后每個成員獲取?/ synchronizing?目錄的所有目錄節(jié)點,也就是?member_i。判斷?i?的值是否已經是成員的個數,如果小于成員個數等待?/synchronizing/start?的出現,如果已經相等就創(chuàng)建?/synchronizing/start。
FIFO?隊列:先進先出隊列,例如實現生產者和消費者模型。
FIFO?隊列用?Zookeeper?實現思路如下:
實現的思路也非常簡單,就是在特定的目錄下創(chuàng)建?SEQUENTIAL?類型的子目錄?/queue_i,這樣就能保證所有成員加入隊列時都是有編號的,出隊列時通過?getChildren( )?方法可以返回當前所有的隊列中的元素,然后消費其中最小的一個,這樣就能保證?FIFO。
總結
以上是生活随笔為你收集整理的zookeeper基本原理及适用场景 转:http://blog.chinaunix.net/uid-26748613-id-4536290.html的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 润小贷上征信吗
- 下一篇: win8笔记本开不了机怎么办 win8笔