本文主要是討論下兩個類似產品:ZooKeeper和Diamond在配置管理這個應用場景上的異同點。
Diamond,顧名思義,寄寓了開發人員對產品穩定性的厚望,希望它像鉆石一樣,提供穩定的配置訪問。Diamond是淘寶網Java中間件團隊的核心產品之一,服務于集團線上很多核心應用。目前已經開源,開源地址在:http://code.taobao.org/p/diamond/wiki/index/。
數據持久性
Diamond主要針對的是持久數據,這些數據有個共同的特點是:集群中一批機器都會使用,但是數據的更新頻率不大,且希望diamond能夠永久存儲。
ZooKeeper即可以存儲持久數據,也可以存儲非持久數據。持久數據和diamond中的持久數據都類似,所謂的非持久數據是指這些數據的生命周期和數據創建者的會話生命周期綁定,一旦會話結束,那么這些非持久數據也會被清除。
推拉模型
本質上,兩個產品都是“拉”模式的,即都是通過客戶端自己去服務器獲取最新數據。具體實現上,兩個產品分別如下:
在Diamond中,客戶端每隔15s輪詢服務器,比對數據是否更新,從而獲取最新數據。
在ZooKeeper中,則是通過客戶端對相應的數據path注冊Watcher,當數據有更新的時候,服務器會有事件通知,注意,這個通知僅僅是告訴客戶端對應的數據有更新了,具體數據內容需要客戶端根據自己的情況來決定是否需要獲取最新數據。
因此在實時性方面,ZooKeeper比Diamond高一些。
服務器數據存儲
在數據存儲上,ZooKeeper和Diamond差別比較大。
首先來看下Diamond的數據存儲。Diamond的數據存儲以mysql數據庫為中心,所有在mysql中的數據都是最新的,客戶端的所有寫請求,都會首先寫入數據庫,同時會dump數據到Server的本地文件中,所有讀請求都是直接走這個靜態文件。
在ZooKeeper中,所有運行時數據都是存儲在內存中,客戶端的所有讀寫操作都是針對這份內存數據來進行的。同時,內存中的數據,ZK會以快照的形式dump到指定文件中去,配合事務日志,幫助服務器在下次重啟的時候,能夠加載正確的數據到內存中去。
數據模型
Diamond的數據都是以行組織的,這也更便于它使用mysql來管理數據。Diamond的基本數據結構包含dataid,group和content,根據group,可以將一組相關的數據組合起來。
ZooKeeper中,使用樹形結構來組織數據,每個節點類型于一個文件系統的路徑,一個節點下面也可以創建多個子節點來規則一些相關的數據。
容災
在容災方面,diamond做得相當的完備:
1. 所有客戶端的讀請求,都是直接讀取服務器端的本地靜態文件,因此,即使數據庫掛了,都不會影響diamond的讀服務。而讀服務在所有使用diamond的應用場景中,占到了絕大部分。
2. Diamond客戶端還保存了數據的快照,客戶端每次從服務器成功獲取數據后,都會把這份數據保存到本地文件系統中,稱為快照文件。這個快照文件是為了防止在服務器無法獲取數據的時候,能夠在這個快照中獲取數據。
3. 客戶端還會有一個容災目錄,變個容災目錄是在服務器完全不可用的時候,運維人員可以手動在這個容災目錄中創建相關目錄結構的數據,diamond就就會優先從這個目錄中獲取數據。
4. 說到這里,我們就可以給diamond的數據獲取優先級作一個總結:
首先都會從容災目錄中獲取數據——無法從容災目錄獲取數據的話,就通過網絡到服務器請求數據——如果無法從服務器獲取數據,那么就從本地的snapshot中獲取數據。
接下來看看ZooKeepe的容災,做得很少,只有以下一點:
1. ZooKeeper實現了paxos算法,有效的解決了分布式單點問題。以一個3臺機器構成的集群為例,任意一臺ZK掛掉,都不會影響集群的數據一致性。
總結:在容災方面,diamond有很大的優勢,也符合了diamond的穩定性要求。
數據大小
Diamond對單個數據的大小,沒有嚴格的限制,通常2M左右的數據大小都是沒有問題的。而在ZooKeeper中,由于全量數據都是存儲在內存中,并且需求進行集群機器間的數據兩步,所以對單個數據的大小有嚴格的限制,默認單個數據節點的最大數據大小是1M。
數據追加與聚合
Diamond支持對數據的追加與聚合功能,即對同一個dataid的寫入操作,可以設置為追加。而ZooKeeper目前不支持,只有覆蓋寫。