二、            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演算法。


五、            資料一致性與paxos演算法