UCloud優(yōu)刻得對象存儲US3元數(shù)據(jù)改造(下)

前言

在《US3元數(shù)據(jù)改造(上)》中,我們介紹了US3的新版本元數(shù)據(jù)服務UKV-Meta,UKV-Meta是基于我們自研的分布式計算存儲分離的KV系統(tǒng)UKV研發(fā)的對象存儲元數(shù)據(jù)服務,下面我們將介紹一下UKV及其相關(guān)組件。

URocksDB

I.簡介

URocksDB是UKV存儲引擎, 是US3研發(fā)小組針對開源RocksDB定制化開發(fā)的Key-Value存儲引擎。

II.RocksDB

LevelDB是由Google開源的,基于LSM Tree的單機KV數(shù)據(jù)庫,其特點是高效,代碼簡潔而優(yōu)美。RocksDB則是Facebook基于LevelDB改造的,它在Level的基礎上加了很多實用的功能,例如Column Family等,具體的差別大家可以Google,也可以實際體驗一下,這里就不再贅述了。

RocksDB目前已經(jīng)運用在許多海內(nèi)外知名的項目中,例如TiKV,MyRocksDB,CrockRoachDB等。

RocksDB使用上的缺點

RocksDB是通過WAL來保證數(shù)據(jù)持久性的,RocksDB先將數(shù)據(jù)寫入磁盤上的WAL,再將數(shù)據(jù)寫入內(nèi)存中的Memtable中,當Memtable達到大小閾值(或者WAL的大小閾值),Memtable中的內(nèi)容會被Flush成有序的SST文件持久化,WAL也會切換成新的WAL(代表舊的數(shù)據(jù)已被持久化,避免WAL過大)。

當RocksDB出現(xiàn)問題當機/重啟后,可以通過重做WAL來使RocksDB內(nèi)存中未持久化的數(shù)據(jù)恢復到之前的狀態(tài)。

但是這里存在兩個問題:

1、RocksDB讀取WAL是線性讀取的, 當為了讀性能把Memtable設置的足夠大時,WAL也可能變得很大(Flush頻率下降),此時如果發(fā)生當機重啟,RocksDB需要足夠長的時間來恢復。

2、如果機器硬盤出現(xiàn)損壞,WAL文件本身被破壞,那么就會出現(xiàn)數(shù)據(jù)損壞。即使做了Raid,也需要很長時間來恢復數(shù)據(jù)。

因此RocksDB的可用性是個大問題。

另外由于LSM架構(gòu),RocksDB的讀性能也會存在問題。

怎么解決?

Share Nothing

為了滿足數(shù)據(jù)一致性這一基本要求,大部分的解決方案都是將一致性協(xié)議置于RocksDB之上,每份數(shù)據(jù)通過一致性協(xié)議提交到多個處于不同機器的RocksDB實例中,以保證數(shù)據(jù)的可靠性和服務的可用性。

典型如TiKV:

TiKV使用3個RocksDB組成一個Group,存儲同一份數(shù)據(jù),實例與實例之間不共享任何資源(CPU、內(nèi)存、存儲),即典型的Share Nothing模式。一旦有一實例數(shù)據(jù)有損失,可通過另外的實例遷移/同步日志,來做恢復。

這種模式解決了可用性問題,也有不錯的擴展性。

但也存在缺點:

•目前CPU的成本偏高,是我們在實際業(yè)務中重點關(guān)注的成本優(yōu)化點之一。而RocksDB(LSM Tree架構(gòu))的一大問題就是寫放大。每個RocksDB為了提高讀性能、降低存儲大小,都會進行不定期Compaction(將數(shù)據(jù)讀出來重新Decode/Encode,再寫入磁盤),編解碼本身會消耗大量的CPU資源。而這樣的多份(一般3份)寫入RocksDB,等于CPU消耗確定會放大3倍。并且寫放大由于提高了寫的次數(shù),即提高SSD的擦寫次數(shù),會顯著減少SSD的壽命,提高系統(tǒng)的成本。

•這種架構(gòu)計算與存儲是耦合在一起的,無論是計算先達到瓶頸,還是存儲先達到瓶頸,兩種狀況雖然不同,時間點也不一致。但通常不管哪種情況都是加機器,因此就會存在不少浪費。

•不易擴展:計算和存儲耦合模式下,存儲擴展通常需要遷移大量數(shù)據(jù)。

存算分離

將數(shù)據(jù)存儲于分布式文件系統(tǒng)中,由其保證數(shù)據(jù)的一致性和存儲的擴容,而計算節(jié)點僅僅處理數(shù)據(jù)的寫入和讀取。

URocksDB使用自研的分布式存儲服務Manul作為底層的存儲,Manul具備數(shù)據(jù)高可靠,服務高可用的特性, 擁有自動容災、擴容等功能。這樣當主節(jié)點寫入一份數(shù)據(jù)時,Manul會自動做三副本同步數(shù)據(jù),而從節(jié)點也能很快同步到主節(jié)點做好的數(shù)據(jù),無需再多做幾次重復的Flush或者Compaction。

當存儲節(jié)點容量不夠時,可單獨加入新的存儲節(jié)點,Manul能夠自動平衡數(shù)據(jù)。

當計算節(jié)點達到瓶頸時,URocksDB擁有獨特的熱點分裂功能,在無需做數(shù)據(jù)遷移的情況下即可快速增加計算節(jié)點,降低熱點壓力。

此時就能夠更精細化的運營計算資源和存儲資源,降低業(yè)務成本。

URocksDB熱備

RocksDB是支持Read Only模式的,但是只是類似于讀一個快照,并不能讀取到主節(jié)點DB的最新數(shù)據(jù)。我們實現(xiàn)了RocksDB Secondary Instance(以下簡稱RSI)模式,能夠通過底層分布式存儲系統(tǒng)實時的讀到另一個RocksDB最新寫入的數(shù)據(jù),使得從節(jié)點不僅能與主節(jié)點共享一份持久化文件數(shù)據(jù),還能保持從節(jié)點內(nèi)存數(shù)據(jù)緊緊跟隨主節(jié)點,提供讀取能力,和快速容災能力。

RSI如何做到數(shù)據(jù)的同步?

利用底層存儲分布式的特點,無論在哪個節(jié)點,從節(jié)點都能看到與主節(jié)點一致的數(shù)據(jù),因而可以由從節(jié)點定期Tail Read并回放主節(jié)點的WAL文件和Manifest文件至其內(nèi)存中,以跟上主節(jié)點的內(nèi)存中最近的數(shù)據(jù)。

RSI容災

如果直接重啟主節(jié)點,那么由于LSM架構(gòu)的缺陷,主節(jié)點必須回放所有WAL日志至內(nèi)存中后,才能對外提供服務。但是只讀的從節(jié)點在同步數(shù)據(jù)后,其Memtable中的數(shù)據(jù)應與主一致。由于從節(jié)點不斷的Tail Read主節(jié)點寫下的WAL日志,因此從節(jié)點只需要先Tail Read 主節(jié)點寫入最新的WAL日志即可同步好數(shù)據(jù)。然后新建一個主節(jié)點對象,再將內(nèi)存中的Memtable和VersionSet切過去即可。

原生RocksDB在重啟時,會先加載所有的WAL日志至內(nèi)存中,再將內(nèi)存中的Memtable全部Flush至Level 0文件。這樣RocksDB就能獲得一個“干凈”的Memtable,然后對外提供服務。但是如果Memtable很大很多,那么Flush將會占用很多的時間。研究了RocksDB的SwitchWAL的過程后,通過代碼改造,把這一部分移動到后臺線程去做了(即把加載的Memtable轉(zhuǎn)為只讀的Immemtable)。

當主節(jié)點掛掉時,從節(jié)點內(nèi)存中即有最新的寫入數(shù)據(jù),所以從節(jié)點搶到ZK的主后,即可將自己從只讀節(jié)點轉(zhuǎn)為可寫節(jié)點,同時因為從同步Manifest文件,從已有所有的數(shù)據(jù)文件信息(與之前的主是同一份),無需進行數(shù)據(jù)遷移,因此可立刻對外提供服務。

采用此種優(yōu)化后,我們線上的節(jié)點容災時間大幅度降低,主從切換P99達到100ms內(nèi)。

UKV

UKV是UCloud優(yōu)刻得自研的計算存儲分離的分布式KV存儲系統(tǒng)。其存儲底座為分布式統(tǒng)一存儲Manul,Manul是具備自動數(shù)據(jù)平衡、異構(gòu)介質(zhì)存儲、EC存儲等功能的高性能、高可用、分布式存儲服務。

UKV提供了集群管理服務,快速備份等常規(guī)功能,還針對US3元數(shù)據(jù)服務設計了數(shù)據(jù)結(jié)構(gòu),使其在UCloud優(yōu)刻得日常的業(yè)務場景下提供更優(yōu)秀的性能。

UKV使用UCloud優(yōu)刻得自研的、由開源RocksDB定制化的URocksDB作為計算節(jié)點,同時依托Manul,實現(xiàn)了主從熱備,熱點節(jié)點快速分裂等特色功能。

熱點分裂

由于UKV采用Range Sharding(因為對象存儲有許多的列表服務,會有大量的范圍讀請求,因為我們采用Range Sharding來滿足此項需求),所以比較容易出現(xiàn)熱點問題,同時我們也需要集群的橫向擴展能力,以保證集群服務能力,所以UCloud優(yōu)刻得為UKV實現(xiàn)了熱點分裂的功能。

設計原則:

1、服務可用性

- 用戶服務不可長時間停止

2、數(shù)據(jù)完整性

- 元數(shù)據(jù)完整性不容有誤

3、失敗回滾處理

- 有任何預期外狀態(tài)能兜得住

4、自動化

- 自動檢測熱點節(jié)點做分裂,自動挑選空閑機器節(jié)點做目標

分裂流程

首先Range信息是持久化在ConfigServer集群的。UKV啟動時,如果它是Active節(jié)點,ConfigServer會給其下發(fā)Range。UKV會與ConfigServer保持心跳,不斷上傳節(jié)點信息,包括容量、QPS、機器狀態(tài)。ConfigServer根據(jù)其狀態(tài)判斷節(jié)點是否觸發(fā)熱點分裂,如果觸發(fā),則會選擇一個空閑節(jié)點作為目標端。

分裂主要分為四個階段:

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

我們主要應用計算存儲分離的能力,利用硬鏈功能和RocksDB的Compaction特性,來保證數(shù)據(jù)不移動,且能過濾非Range數(shù)據(jù)。

分裂時間

我們單節(jié)點大小上限設置為256G,實際線上300ms以內(nèi)就可完成分裂,配合上上層的重試,分裂過程中用戶是完全無感知的。

數(shù)據(jù)遷移

由于新老列表數(shù)據(jù)存儲結(jié)構(gòu)不一致(新的是字典序),老的是先目錄再文件,所以還做了列表服務Proxy的兼容開發(fā), 避免上層業(yè)務改動

以現(xiàn)有擴容方式,無縫加入UKV-Meta,縮小影響范圍。

我們研發(fā)了專用的Migration服務來為我們的UKV-Meta進行遷移,將存在于老架構(gòu)的元數(shù)據(jù)遷移至UKV-Meta,以便將老架構(gòu)占用的機器下機,降低業(yè)務成本。

Migration服務可以在不影響用戶業(yè)務的情況下,安全的進行數(shù)據(jù)熱遷移,保證數(shù)據(jù)的一致性,同時還具備遷移數(shù)據(jù)實時校驗功能,防止遷移過程中出現(xiàn)問題。

總結(jié)

由于當前芯片、機柜等硬件資源價格高昂,使得云計算公司對CPU資源、存儲資源的使用提出了更高、更精細化的需求。計算存儲耦合的方式在擴容集群、擴充CPU、存儲資源時,不僅會引發(fā)數(shù)據(jù)的Reshuffle,還會消耗比較大的網(wǎng)絡帶寬、以及CPU資源。

通過分離存儲資源、計算資源,獨立規(guī)劃存儲、計算的資源規(guī)格和容量,使得計算資源的擴容、縮容、釋放,均可以比較快的完成,并且不會帶來額外的數(shù)據(jù)搬遷代價。存儲、計算也可以更好的結(jié)合各自的特征,選擇更適合自己的資源規(guī)格和設計。

(免責聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準確性及可靠性,但不保證有關(guān)資料的準確性及可靠性,讀者在使用前請進一步核實,并對任何自主決定的行為負責。本網(wǎng)站對有關(guān)資料所引致的錯誤、不確或遺漏,概不負任何法律責任。
任何單位或個人認為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權(quán)或存在不實內(nèi)容時,應及時向本網(wǎng)站提出書面權(quán)利通知或不實情況說明,并提供身份證明、權(quán)屬證明及詳細侵權(quán)或不實情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關(guān)文章源頭核實,溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。 )