前言
在《US3元數(shù)據(jù)改造(上)》中,我們介紹了US3的新版本元數(shù)據(jù)服務(wù)UKV-Meta,UKV-Meta是基于我們自研的分布式計算存儲分離的KV系統(tǒng)UKV研發(fā)的對象存儲元數(shù)據(jù)服務(wù),下面我們將介紹一下UKV及其相關(guān)組件。
URocksDB
I.簡介
URocksDB是UKV存儲引擎, 是US3研發(fā)小組針對開源RocksDB定制化開發(fā)的Key-Value存儲引擎。
II.RocksDB
LevelDB是由Google開源的,基于LSM Tree的單機(jī)KV數(shù)據(jù)庫,其特點(diǎn)是高效,代碼簡潔而優(yōu)美。RocksDB則是Facebook基于LevelDB改造的,它在Level的基礎(chǔ)上加了很多實(shí)用的功能,例如Column Family等,具體的差別大家可以Google,也可以實(shí)際體驗(yàn)一下,這里就不再贅述了。
RocksDB目前已經(jīng)運(yùn)用在許多海內(nèi)外知名的項(xiàng)目中,例如TiKV,MyRocksDB,CrockRoachDB等。
RocksDB使用上的缺點(diǎn)
RocksDB是通過WAL來保證數(shù)據(jù)持久性的,RocksDB先將數(shù)據(jù)寫入磁盤上的WAL,再將數(shù)據(jù)寫入內(nèi)存中的Memtable中,當(dāng)Memtable達(dá)到大小閾值(或者WAL的大小閾值),Memtable中的內(nèi)容會被Flush成有序的SST文件持久化,WAL也會切換成新的WAL(代表舊的數(shù)據(jù)已被持久化,避免WAL過大)。
當(dāng)RocksDB出現(xiàn)問題當(dāng)機(jī)/重啟后,可以通過重做WAL來使RocksDB內(nèi)存中未持久化的數(shù)據(jù)恢復(fù)到之前的狀態(tài)。
但是這里存在兩個問題:
1、RocksDB讀取WAL是線性讀取的, 當(dāng)為了讀性能把Memtable設(shè)置的足夠大時,WAL也可能變得很大(Flush頻率下降),此時如果發(fā)生當(dāng)機(jī)重啟,RocksDB需要足夠長的時間來恢復(fù)。
2、如果機(jī)器硬盤出現(xiàn)損壞,WAL文件本身被破壞,那么就會出現(xiàn)數(shù)據(jù)損壞。即使做了Raid,也需要很長時間來恢復(fù)數(shù)據(jù)。
因此RocksDB的可用性是個大問題。
另外由于LSM架構(gòu),RocksDB的讀性能也會存在問題。
怎么解決?
Share Nothing
為了滿足數(shù)據(jù)一致性這一基本要求,大部分的解決方案都是將一致性協(xié)議置于RocksDB之上,每份數(shù)據(jù)通過一致性協(xié)議提交到多個處于不同機(jī)器的RocksDB實(shí)例中,以保證數(shù)據(jù)的可靠性和服務(wù)的可用性。
典型如TiKV:
TiKV使用3個RocksDB組成一個Group,存儲同一份數(shù)據(jù),實(shí)例與實(shí)例之間不共享任何資源(CPU、內(nèi)存、存儲),即典型的Share Nothing模式。一旦有一實(shí)例數(shù)據(jù)有損失,可通過另外的實(shí)例遷移/同步日志,來做恢復(fù)。
這種模式解決了可用性問題,也有不錯的擴(kuò)展性。
但也存在缺點(diǎn):
•目前CPU的成本偏高,是我們在實(shí)際業(yè)務(wù)中重點(diǎn)關(guān)注的成本優(yōu)化點(diǎn)之一。而RocksDB(LSM Tree架構(gòu))的一大問題就是寫放大。每個RocksDB為了提高讀性能、降低存儲大小,都會進(jìn)行不定期Compaction(將數(shù)據(jù)讀出來重新Decode/Encode,再寫入磁盤),編解碼本身會消耗大量的CPU資源。而這樣的多份(一般3份)寫入RocksDB,等于CPU消耗確定會放大3倍。并且寫放大由于提高了寫的次數(shù),即提高SSD的擦寫次數(shù),會顯著減少SSD的壽命,提高系統(tǒng)的成本。
•這種架構(gòu)計算與存儲是耦合在一起的,無論是計算先達(dá)到瓶頸,還是存儲先達(dá)到瓶頸,兩種狀況雖然不同,時間點(diǎn)也不一致。但通常不管哪種情況都是加機(jī)器,因此就會存在不少浪費(fèi)。
•不易擴(kuò)展:計算和存儲耦合模式下,存儲擴(kuò)展通常需要遷移大量數(shù)據(jù)。
存算分離
將數(shù)據(jù)存儲于分布式文件系統(tǒng)中,由其保證數(shù)據(jù)的一致性和存儲的擴(kuò)容,而計算節(jié)點(diǎn)僅僅處理數(shù)據(jù)的寫入和讀取。
URocksDB使用自研的分布式存儲服務(wù)Manul作為底層的存儲,Manul具備數(shù)據(jù)高可靠,服務(wù)高可用的特性, 擁有自動容災(zāi)、擴(kuò)容等功能。這樣當(dāng)主節(jié)點(diǎn)寫入一份數(shù)據(jù)時,Manul會自動做三副本同步數(shù)據(jù),而從節(jié)點(diǎn)也能很快同步到主節(jié)點(diǎn)做好的數(shù)據(jù),無需再多做幾次重復(fù)的Flush或者Compaction。
當(dāng)存儲節(jié)點(diǎn)容量不夠時,可單獨(dú)加入新的存儲節(jié)點(diǎn),Manul能夠自動平衡數(shù)據(jù)。
當(dāng)計算節(jié)點(diǎn)達(dá)到瓶頸時,URocksDB擁有獨(dú)特的熱點(diǎn)分裂功能,在無需做數(shù)據(jù)遷移的情況下即可快速增加計算節(jié)點(diǎn),降低熱點(diǎn)壓力。
此時就能夠更精細(xì)化的運(yùn)營計算資源和存儲資源,降低業(yè)務(wù)成本。
URocksDB熱備
RocksDB是支持Read Only模式的,但是只是類似于讀一個快照,并不能讀取到主節(jié)點(diǎn)DB的最新數(shù)據(jù)。我們實(shí)現(xiàn)了RocksDB Secondary Instance(以下簡稱RSI)模式,能夠通過底層分布式存儲系統(tǒng)實(shí)時的讀到另一個RocksDB最新寫入的數(shù)據(jù),使得從節(jié)點(diǎn)不僅能與主節(jié)點(diǎn)共享一份持久化文件數(shù)據(jù),還能保持從節(jié)點(diǎn)內(nèi)存數(shù)據(jù)緊緊跟隨主節(jié)點(diǎn),提供讀取能力,和快速容災(zāi)能力。
RSI如何做到數(shù)據(jù)的同步?
利用底層存儲分布式的特點(diǎn),無論在哪個節(jié)點(diǎn),從節(jié)點(diǎn)都能看到與主節(jié)點(diǎn)一致的數(shù)據(jù),因而可以由從節(jié)點(diǎn)定期Tail Read并回放主節(jié)點(diǎn)的WAL文件和Manifest文件至其內(nèi)存中,以跟上主節(jié)點(diǎn)的內(nèi)存中最近的數(shù)據(jù)。
RSI容災(zāi)
如果直接重啟主節(jié)點(diǎn),那么由于LSM架構(gòu)的缺陷,主節(jié)點(diǎn)必須回放所有WAL日志至內(nèi)存中后,才能對外提供服務(wù)。但是只讀的從節(jié)點(diǎn)在同步數(shù)據(jù)后,其Memtable中的數(shù)據(jù)應(yīng)與主一致。由于從節(jié)點(diǎn)不斷的Tail Read主節(jié)點(diǎn)寫下的WAL日志,因此從節(jié)點(diǎn)只需要先Tail Read 主節(jié)點(diǎn)寫入最新的WAL日志即可同步好數(shù)據(jù)。然后新建一個主節(jié)點(diǎn)對象,再將內(nèi)存中的Memtable和VersionSet切過去即可。
原生RocksDB在重啟時,會先加載所有的WAL日志至內(nèi)存中,再將內(nèi)存中的Memtable全部Flush至Level 0文件。這樣RocksDB就能獲得一個“干凈”的Memtable,然后對外提供服務(wù)。但是如果Memtable很大很多,那么Flush將會占用很多的時間。研究了RocksDB的SwitchWAL的過程后,通過代碼改造,把這一部分移動到后臺線程去做了(即把加載的Memtable轉(zhuǎn)為只讀的Immemtable)。
當(dāng)主節(jié)點(diǎn)掛掉時,從節(jié)點(diǎn)內(nèi)存中即有最新的寫入數(shù)據(jù),所以從節(jié)點(diǎn)搶到ZK的主后,即可將自己從只讀節(jié)點(diǎn)轉(zhuǎn)為可寫節(jié)點(diǎn),同時因?yàn)閺耐組anifest文件,從已有所有的數(shù)據(jù)文件信息(與之前的主是同一份),無需進(jìn)行數(shù)據(jù)遷移,因此可立刻對外提供服務(wù)。
采用此種優(yōu)化后,我們線上的節(jié)點(diǎn)容災(zāi)時間大幅度降低,主從切換P99達(dá)到100ms內(nèi)。
UKV
UKV是UCloud優(yōu)刻得自研的計算存儲分離的分布式KV存儲系統(tǒng)。其存儲底座為分布式統(tǒng)一存儲Manul,Manul是具備自動數(shù)據(jù)平衡、異構(gòu)介質(zhì)存儲、EC存儲等功能的高性能、高可用、分布式存儲服務(wù)。
UKV提供了集群管理服務(wù),快速備份等常規(guī)功能,還針對US3元數(shù)據(jù)服務(wù)設(shè)計了數(shù)據(jù)結(jié)構(gòu),使其在UCloud優(yōu)刻得日常的業(yè)務(wù)場景下提供更優(yōu)秀的性能。
UKV使用UCloud優(yōu)刻得自研的、由開源RocksDB定制化的URocksDB作為計算節(jié)點(diǎn),同時依托Manul,實(shí)現(xiàn)了主從熱備,熱點(diǎn)節(jié)點(diǎn)快速分裂等特色功能。
熱點(diǎn)分裂
由于UKV采用Range Sharding(因?yàn)閷ο蟠鎯τ性S多的列表服務(wù),會有大量的范圍讀請求,因?yàn)槲覀儾捎肦ange Sharding來滿足此項(xiàng)需求),所以比較容易出現(xiàn)熱點(diǎn)問題,同時我們也需要集群的橫向擴(kuò)展能力,以保證集群服務(wù)能力,所以UCloud優(yōu)刻得為UKV實(shí)現(xiàn)了熱點(diǎn)分裂的功能。
設(shè)計原則:
1、服務(wù)可用性
- 用戶服務(wù)不可長時間停止
2、數(shù)據(jù)完整性
- 元數(shù)據(jù)完整性不容有誤
3、失敗回滾處理
- 有任何預(yù)期外狀態(tài)能兜得住
4、自動化
- 自動檢測熱點(diǎn)節(jié)點(diǎn)做分裂,自動挑選空閑機(jī)器節(jié)點(diǎn)做目標(biāo)
分裂流程
首先Range信息是持久化在ConfigServer集群的。UKV啟動時,如果它是Active節(jié)點(diǎn),ConfigServer會給其下發(fā)Range。UKV會與ConfigServer保持心跳,不斷上傳節(jié)點(diǎn)信息,包括容量、QPS、機(jī)器狀態(tài)。ConfigServer根據(jù)其狀態(tài)判斷節(jié)點(diǎn)是否觸發(fā)熱點(diǎn)分裂,如果觸發(fā),則會選擇一個空閑節(jié)點(diǎn)作為目標(biāo)端。
分裂主要分為四個階段:
1.SPLITTING_BEGIN
ConfigServer發(fā)起SplitRequest
2.HARDLINK_BEGIN
UKVRequest定期更新其硬鏈狀態(tài)(向ConfigServer發(fā)送請求,如成功順便帶上計算的Range)
3.TARGET_OPEN
ConfigServer向Target發(fā)起OpenRequest請求(Target Open但不啟動Compaction)
4.OPEN_COMPACTION_FILTER
ConfigServer使用心跳來讓Source和Target開啟Compaction Filter
我們主要應(yīng)用計算存儲分離的能力,利用硬鏈功能和RocksDB的Compaction特性,來保證數(shù)據(jù)不移動,且能過濾非Range數(shù)據(jù)。
分裂時間
我們單節(jié)點(diǎn)大小上限設(shè)置為256G,實(shí)際線上300ms以內(nèi)就可完成分裂,配合上上層的重試,分裂過程中用戶是完全無感知的。
數(shù)據(jù)遷移
由于新老列表數(shù)據(jù)存儲結(jié)構(gòu)不一致(新的是字典序),老的是先目錄再文件,所以還做了列表服務(wù)Proxy的兼容開發(fā), 避免上層業(yè)務(wù)改動
以現(xiàn)有擴(kuò)容方式,無縫加入UKV-Meta,縮小影響范圍。
我們研發(fā)了專用的Migration服務(wù)來為我們的UKV-Meta進(jìn)行遷移,將存在于老架構(gòu)的元數(shù)據(jù)遷移至UKV-Meta,以便將老架構(gòu)占用的機(jī)器下機(jī),降低業(yè)務(wù)成本。
Migration服務(wù)可以在不影響用戶業(yè)務(wù)的情況下,安全的進(jìn)行數(shù)據(jù)熱遷移,保證數(shù)據(jù)的一致性,同時還具備遷移數(shù)據(jù)實(shí)時校驗(yàn)功能,防止遷移過程中出現(xiàn)問題。
總結(jié)
由于當(dāng)前芯片、機(jī)柜等硬件資源價格高昂,使得云計算公司對CPU資源、存儲資源的使用提出了更高、更精細(xì)化的需求。計算存儲耦合的方式在擴(kuò)容集群、擴(kuò)充CPU、存儲資源時,不僅會引發(fā)數(shù)據(jù)的Reshuffle,還會消耗比較大的網(wǎng)絡(luò)帶寬、以及CPU資源。
通過分離存儲資源、計算資源,獨(dú)立規(guī)劃存儲、計算的資源規(guī)格和容量,使得計算資源的擴(kuò)容、縮容、釋放,均可以比較快的完成,并且不會帶來額外的數(shù)據(jù)搬遷代價。存儲、計算也可以更好的結(jié)合各自的特征,選擇更適合自己的資源規(guī)格和設(shè)計。
(免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請進(jìn)一步核實(shí),并對任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對有關(guān)資料所引致的錯誤、不確或遺漏,概不負(fù)任何法律責(zé)任。
任何單位或個人認(rèn)為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權(quán)或存在不實(shí)內(nèi)容時,應(yīng)及時向本網(wǎng)站提出書面權(quán)利通知或不實(shí)情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實(shí)情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關(guān)文章源頭核實(shí),溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。 )