diamond簡介
diamond是一個管理持久配置(持久配置是指配置資料會持久化到磁盤和資料庫中)的系統。無可厚非,淘寶内部正在使用diamond,在淘寶内部的絕大多數系統的配置都是由diamond統一管理的。diamond最大的特點就是簡單、可靠、易用。diamond的簡單是指diamond整體結構非常簡單,進而減少了出錯的可能性;diamond的可靠是指應用方在任何情況下都可以啟動,例如:淘寶的核心系統最初一年多是由diamond所管理,在這期間并沒有發生什麼大的故障;diamond的易用是指用戶端使用隻需要兩行代碼,暴露出的接口都非常簡單,易于了解。
對于應用系統而言,diamond為其提供擷取配置的服務,應用不僅可以在啟動時從diamond擷取相關的配置,而且可以在運作中對配置資料的變化進行感覺并擷取變化後的配置資料。
diamond核心原理
diamond核心原理主要包括
- server叢集的資料同步
- client擷取server位址、
- client從server擷取資料
- client運作時感覺server的資料變化,這四部分。
1.server叢集的資料同步
diamond-server将資料存儲在mysql和本地檔案中,mysql是一個中心,
diamond認為存儲在mysql中的資料絕對正确,除此之外,server會将資料存儲在本地檔案中。
同步資料有兩種方式:
寫入完成後發送一個HTTP請求給叢集中的其他server,其他server收到請求,
從mysql中dump剛剛寫入的資料至本地檔案。
server啟動後會啟動一個定時任務,定時從mysql中dump所有資料至本地檔案。
2.client擷取server位址
diamond-client在使用時沒有指定server位址的代碼,位址擷取對使用者是透明的。
diamond-client使用前需要在本地進行正确的域名綁定,啟動時它會根據域名綁定,
去對應環境的位址伺服器上擷取diamond-server位址清單。
擷取的位址清單,會儲存在client本地,當出現網絡異常,
無法從網絡擷取位址清單時,client會使用本地儲存的位址清單。
client啟動後會啟動一個定時任務,定時從HTTP server上擷取位址清單并儲存在本地,以保證位址是最新的。
3.client從server擷取資料
client調用getAvailableConfigInfomation(), 即可擷取一份最新的可用的配置資料,
為了避免短時間内大量的擷取資料請求發向server,client端實作了一個帶有過期時間的緩存,
client将本次擷取到的資料儲存在緩存中,在過期時間内的所有請求,
都傳回緩存内的資料,不向server送出請求。
4 client運作時感覺server的資料變化
這是diamond最為核心的一個功能。這個特性是通過比較client和server的資料的MD5值實作的。
client在啟動并第一次擷取資料後,會将資料的MD5儲存在記憶體中,并且在啟動時會啟動一個定時任務,
定時去server檢查資料是否變化。每次檢查時,client将MD5傳給server,
server比較傳來的MD5和自身記憶體中的MD5是否相同,如果相同,
說明資料沒變,傳回一個标示資料不變的字元串給client;如果不同,
說明資料變了,傳回變化資料的dataId和group給client. client收到變化資料的dataId和group,
再去server請求一次資料,拿回資料後回調監聽器。
架構
a. 作為一個配置中心,diamond的功能分為釋出和訂閱兩部分。
因為diamond存放的是持久資料,這些資料的變化頻率不會很高,甚至很低,
是以釋出采用手工的形式,通過diamond背景管理界面釋出;
訂閱是diamond的核心功能,訂閱通過diamond-client的API進行。
b. diamond服務端采用mysql加本地檔案的形式存放配置資料。
釋出資料時,資料先寫到mysql,再寫到本地檔案;訂閱資料時,直接擷取本地檔案,不查詢資料庫,這樣可以最大程度減少對資料庫的壓力。
c. diamond服務端是一個叢集,叢集中的每台機器連接配接同一個mysql,叢集之間的資料同步通過兩種方式進行,
一是每台server定時去mysql dump資料到本地檔案,
二是某一台server接收釋出資料請求,在更新完mysql和本機的本地檔案後,
發送一個HTTP請求(通知)到叢集中的其他幾台server,其他server收到通知,去mysql中将剛剛更新的資料dump到本地檔案。
d. 每一台server前端都有一個nginx,用來做流量控制。
e. 圖中沒有将位址伺服器畫出,位址伺服器是一台有域名的機器,
上面運作有一個HTTP server,其中有一個靜态檔案,
存放着diamond伺服器的位址清單。用戶端啟動時,
根據自身的域名綁定,連接配接到位址伺服器,取回diamond伺服器的位址清單,從中随機選擇一台diamond伺服器進行連接配接。
容災機制
diamond容災機制涉及到client和server兩部分,主要包括以下幾個方面:
a. server存儲資料的方式
server存儲資料是“資料庫 + 本地檔案”的方式,
叢集間的資料同步我們在之前的文章中講過(請參考專題二的原理部分),
client訂閱資料時,通路的是本地檔案,不查詢資料庫,這樣即使資料庫出問題了,仍然不影響client的訂閱。
b. server是一個叢集
這是一個基本的容災機制,叢集中的一台server不可用了,
client發現後可以自動切換到其他server上進行通路,自動切換在client内部實作。
c. client儲存snapshot
client每次從server擷取到資料後,都會将資料儲存在本地檔案系統,
diamond稱之為snapshot,即資料快照。
當client下次啟動發現在逾時時間内所有server均不可用(可能是網絡故障),它會使用snapshot中的資料快照進行啟動。
d. client校驗MD5
client每次從server擷取到資料後,都會進行MD5校驗(資料儲存在response body,MD5儲存在response header),
以防止因網絡故障造成的資料不完整,MD5校驗不通過直接抛出異常。
e. client與server分離
client可以和server完全分離,單獨使用,diamond定義了一個“容災目錄”的概念,
client在啟動時會建立這個目錄,每次主動擷取資料(即調用getAvailableConfigInfomation()方法),
都會優先從“容災目錄”擷取資料,如果client按照一個固定的規則,在“容災目錄”下配置了需要的資料,
那麼client直接擷取到資料傳回,不再通過網絡從diamond-server擷取資料。
同樣的,在每次輪詢時,都會優先輪詢“容災目錄”,如果發現配置還存在于其中,則不再向server發出輪詢請求。
以上的情形, 會持續到“容災目錄”的配置資料被删除為止。
根據以上的容災機制,我們可以總結一下diamond整個系統完全不可用的條件:
資料庫不可用;
所有server均不可用;
client主動删除了snapshot;
client沒有備份配置資料,導緻其不能配置"容災目錄";