天天看點

zookeeper的虛拟檔案系統

ZooKeeper是分布式應用中的一種架構。

ZooKeeper能幹什麼哪?我總結了一句話,就是:ZooKeeper是用來保證資料在叢集間的事務性一緻。

我們細細品一下這句話,可以獲得以下認識:

ZK是叢集部署的;

叢集之間是傳遞資料的;

叢集之間傳遞的資料必須保證在各個節點之間的事務性一緻;

這是我們獲得的認識。

下面談一談,ZK到底是怎麼一回事?

簡單地講,ZK是一個檔案系統,類似于Linux的檔案,有根路徑“/”,根目錄下各級子目錄,可以有一級一級的子目錄。在ZK中,目錄被稱作“節點”。與linux不同的是,ZK的節點是可以存放資料的。也就是說,ZK中儲存的資料是存放在節點中的。

既然節點是一級級的。那麼,必然有父節點,有子節點。談這個話題有什麼用?繼續向下看。

在ZK中,還有一個很重要的特性,就是事件的監聽機制。

當我們想在ZK中建立節點、删除節點、修改節點值等時候,都會産生事件,注冊了事件監聽器的類,就可以獲得這些事件。換句話說,隻要ZK的節點變化了,那麼資料肯定變化,那麼注冊器通過監控節點的變化就可以知道資料的變化。那麼而這正是ZK的無比強大之處。

總結一下,ZK中資料的通知機制是通過對節點變化的監聽機制實作的。

下面,看一下ZK的應用場景吧!

統一命名服務

舉例子,公司有很多業務系統,這些業務系統都需要某種單據号,那麼這個單據号肯定在所有系統中都是唯一的,在不指定哪個系統産生該單據号的情況下,可以使用ZK做這件事情。ZK可以保證原子性,不會因為多個系統的争搶造成不一緻。

統一配置管理

比如,公司的一套産品部署了N多的客戶,你現在要對配置檔案更新,那麼你不會挨家挨戶的去修改,那真是累死人的。我們可以在ZK中設定一個更新位址,讓所有的産品都從這個位址下載下傳。當需要更新的時候,可以修改該節點的值。每次更新,改一次值。這樣,所有客戶那邊就可以自動更新了,不必我們跑來跑去了。

叢集中管理

對于運維工作而言,叢集的管理非常重要,有伺服器down掉那是非常要緊的事情,必須第一時間知道。那麼,伺服器down有可能是斷電,網絡中斷等各種原因。伺服器 一旦down掉,它是沒有辦法向外界發送求救信号的。怎麼辦?當伺服器啟動時,在ZK叢集建立一個連接配接,如果伺服器down掉,那麼連接配接就中斷了,那麼ZK那麼就知道有伺服器down掉了,這時候ZK就可以對外發送求救信号了。

獨占鎖實作

在多系統架構中,有些資源是獨占的,也就是說同一時刻隻能有一個系統在用。如果是虛拟機内部,可以通過synchronized關鍵字實作,但是系統之間就無能為力了。可以這樣做:當系統占用資源時,去ZK建立一個指定節點;如果其他系統想要占用資源,也要去建立相同的節點,但是發現已經被建立了,那麼就不能再次建立,隻能等待。這就實作了獨占鎖機制了。

ZK的特性還有很多,需要我們把這些特性應用到具體的工作中。

有的同學想:為什麼原來沒有這樣的東西啊?因為ZK是分布式系統,在單機下是用不上這套東西的。隻有到了分布式環境下,才有ZK的用武之地!

二、            zookeeper提供了什麼

簡單的說,zookeeper=檔案系統+通知機制。

1、 檔案系統

Zookeeper維護一個類似檔案系統的資料結構:

[attach]6801[/attach]

每個子目錄項如 NameService 都被稱作為 znode,和檔案系統一樣,我們能夠自由的增加、删除znode,在一個znode下增加、删除子znode,唯一的不同在于znode是可以存儲資料的。

有四種類型的znode:

1、PERSISTENT-持久化目錄節點

用戶端與zookeeper斷開連接配接後,該節點依舊存在

2、 PERSISTENT_SEQUENTIAL-持久化順序編号目錄節點

用戶端與zookeeper斷開連接配接後,該節點依舊存在,隻是Zookeeper給該節點名稱進行順序編号

3、EPHEMERAL-臨時目錄節點

用戶端與zookeeper斷開連接配接後,該節點被删除

4、EPHEMERAL_SEQUENTIAL-臨時順序編号目錄節點

用戶端與zookeeper斷開連接配接後,該節點被删除,隻是Zookeeper給該節點名稱進行順序編号

2、 通知機制

用戶端注冊監聽它關心的目錄節點,當目錄節點發生變化(資料改變、被删除、子目錄節點增加删除)時,zookeeper會通知用戶端。

就這麼簡單,下面我們看看能做點什麼呢?

三、            我們能用zookeeper做什麼

1、 命名服務

這個似乎最簡單,在zookeeper的檔案系統裡建立一個目錄,即有唯一的path。在我們使用tborg無法确定上遊程式的部署機器時即可與下遊程式約定好path,通過path即能互相探索發現,不見不散了。

2、 配置管理

程式總是需要配置的,如果程式分散部署在多台機器上,要逐個改變配置就變得困難。好吧,現在把這些配置全部放到zookeeper上去,儲存在 Zookeeper 的某個目錄節點中,然後所有相關應用程式對這個目錄節點進行監聽,一旦配置資訊發生變化,每個應用程式就會收到 Zookeeper 的通知,然後從 Zookeeper 擷取新的配置資訊應用到系統中就好。

[attach]6802[/attach]

3、 叢集管理

所謂叢集管理無在乎兩點:是否有機器退出和加入、選舉master。

對于第一點,所有機器約定在父目錄GroupMembers下建立臨時目錄節點,然後監聽父目錄節點的子節點變化消息。一旦有機器挂掉,該機器與zookeeper的連接配接斷開,其所建立的臨時目錄節點被删除,所有其他機器都收到通知:某個兄弟目錄被删除,于是,所有人都知道:它上船了。新機器加入也是類似,所有機器收到通知:新兄弟目錄加入,highcount又有了。

對于第二點,我們稍微改變一下,所有機器建立臨時順序編号目錄節點,每次選取編号最小的機器作為master就好。

[attach]6803[/attach]

4、  分布式鎖

有了zookeeper的一緻性檔案系統,鎖的問題變得容易。鎖服務可以分為兩類,一個是保持獨占,另一個是控制時序。

對于第一類,我們将zookeeper上的一個znode看作是一把鎖,通過createznode的方式來實作。所有用戶端都去建立 /distribute_lock 節點,最終成功建立的那個用戶端也即擁有了這把鎖。廁所有言:來也沖沖,去也沖沖,用完删除掉自己建立的distribute_lock 節點就釋放出鎖。

對于第二類, /distribute_lock 已經預先存在,所有用戶端在它下面建立臨時順序編号目錄節點,和選master一樣,編号最小的獲得鎖,用完删除,依次友善。

5、隊列管理

兩種類型的隊列:

1、 同步隊列,當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達。

2、隊列按照 FIFO 方式進行入隊和出隊操作。

第一類,在約定目錄下建立臨時目錄節點,監聽節點數目是否是我們要求的數目。

第二類,和分布式鎖服務中的控制時序場景基本原理一緻,入列有編号,出列按編号。

         終于了解完我們能用zookeeper做什麼了,可是作為一個程式員,我們總是想狂熱了解zookeeper是如何做到這一點的,單點維護一個檔案系統沒有什麼難度,可是如果是一個叢集維護一個檔案系統保持資料的一緻性就非常困難了。

四、            分布式與資料複制

Zookeeper作為一個叢集提供一緻的資料服務,自然,它要在所有機器間做資料複制。資料複制的好處:

1、 容錯

一個節點出錯,不緻于讓整個系統停止工作,别的節點可以接管它的工作;

2、提高系統的擴充能力

把負載分布到多個節點上,或者增加節點來提高系統的負載能力;

3、提高性能

讓用戶端本地通路就近的節點,提高使用者通路速度。

從用戶端讀寫通路的透明度來看,資料複制叢集系統分下面兩種:

1、寫主(WriteMaster)

對資料的修改送出給指定的節點。讀無此限制,可以讀取任何一個節點。這種情況下用戶端需要對讀與寫進行差別,俗稱讀寫分離;

2、寫任意(Write Any)

對資料的修改可送出給任意的節點,跟讀一樣。這種情況下,用戶端對叢集節點的角色與變化透明。

對zookeeper來說,它采用的方式是寫任意。通過增加機器,它的讀吞吐能力和響應能力擴充性非常好,而寫,随着機器的增多吞吐能力肯定下降(這也是它建立observer的原因),而響應能力則取決于具體實作方式,是延遲複制保持最終一緻性,還是立即複制快速響應。

我們關注的重點還是在如何保證資料在叢集所有機器的一緻性,這就涉及到paxos算法。

本文轉自 yntmdr 51CTO部落格,原文連結:http://blog.51cto.com/yntmdr/1958434,如需轉載請自行聯系原作者

繼續閱讀