Ceph Crimson-Seastore 實現(xiàn)介紹

背景

Seastore 作為 OSD 下一代存儲引擎厕九,相比 Bluestore 做了諸多改進。Bluestore 在 NVMe 上最明顯的瓶頸是 kv-sync-thread饶囚,即順序提交元數(shù)據(jù)到 RocksDB 的線程越锈,Seastore 則完全去除了 RocksDB绍些,并且實現(xiàn)了 extent 粒度的寫時復(fù)制,避免了上一代 OSD 中一個 read 請求阻塞整個 pg 的情況淤堵。

Seastore 相比 Bluestore 的明顯變化:

  • 使用 seastar 框架寝衫。全新的,更簡潔的異步編程模式拐邪,通過 RTC 模式去除傳統(tǒng)多線程模式帶來的損耗慰毅。
  • 獨立管理元數(shù)據(jù),不再依賴 RocksDB扎阶。
  • 讀不再影響寫入汹胃。
  • 實現(xiàn)了兩種類型的磁盤管理后端:Segement Backend(Append 方式) 和 RandomBlock Backend(傳統(tǒng)方式),且 Segment Backend 支持 ZNS 和 SMR 磁盤乘陪。
整體層次

實現(xiàn)介紹

一统台、如何去除的 RocksDB?

上一代的 OSD 中對 RocksDB 的需求來自兩方面:一是對外提供 kv 接口存儲 omap啡邑、xattr贱勃,二是內(nèi)部記錄一些元數(shù)據(jù),比如每個 object 對應(yīng)的物理地址。
SeaStore 仍然保留了處理 omap贵扰、xattr 的接口仇穗,但針對不同 kv 場景,將 kv 數(shù)據(jù)分為了 3 種:

  • Onode
  • Omap戚绕、xattr
  • lba纹坐、backref

這三種數(shù)據(jù)都是通過 B+ tree 管理,但每一種數(shù)據(jù)的 B+ tree 具體實現(xiàn)有區(qū)別舞丛。對于 Onode 實現(xiàn)了一個 Staged FLTree耘子;對于 LBA 和 Backref 這類信息則實現(xiàn)了一個 FixedKVBtree;而對于 omap球切、xattr 這種 kv 場景谷誓,則實現(xiàn)了一個 kv 長度可變的B+ tree。拋開具體實現(xiàn)吨凑,三類數(shù)據(jù)每次的操作都是從樹的 root 節(jié)點開始查找捍歪,最終在葉子結(jié)點上更新數(shù)據(jù),中間可能會有分裂合并發(fā)生鸵钝。

下面針對每一種做進一步說明糙臼。

1. 關(guān)于 Onode

每個 object 對應(yīng)一個 onode,每個 onode 有唯一的 key恩商,根據(jù) key 可尋址到 onode变逃,一個 onode key 由 3 部分組成:

shard (ghobject.shard_id), pool (ghobject.hobj.pool), crush (ghobject.hobj.hash_reverse_bits)
oid (object name), ns (obj name space)
gen, snap
這 3 部分信息都是從 ghobject 中獲得,這也是 OSD層的 object 到 Seastore 層的 onode 的橋梁痕届。

onode 中(onode value)記錄了一個 object 的元信息韧献,其中比較重要的有 3 個:

  • data 的邏輯地址
  • xattr root 的邏輯地址
  • omap root 的邏輯地址

每次操作 object 都要先獲得 onode末患,根據(jù) onode 中記錄的邏輯地址再去處理相關(guān)數(shù)據(jù)研叫。onode 是由單獨的樹(FLTree)管理,樹的根節(jié)點地址記錄在 super block 中璧针。 FLTree 名字來源從代碼中沒有找到嚷炉,不過整個 onode 的管理本質(zhì)上仍是一棵 B+ 樹化撕,比較特別的地方是FLTree 使用了 “staged” 方式管理:將 key 分層帆竹,通過類似前綴樹的方式減少冗余信息坷檩。

如果不使用“staged”方式靡菇,那么每個 val 都要記錄一個獨立完整的 key个盆,顯然前兩層會有大量冗余斗幼,畢竟 object 會很多辙芍,而 shard 瞻想、pool 這些變化并不多胞枕。下面的圖片展示了對于同一個 object 的不同 snap杆煞,普通管理方式和 staged 方式區(qū)別,其中大框表示一個 extent,對應(yīng)一塊物理磁盤空間决乎,所有數(shù)據(jù)順序?qū)懭?extent队询,每個小框表示相應(yīng)類型的數(shù)據(jù):

通過 staged fltree 節(jié)省空間

2. 關(guān)于 Omap

每個 onode 有兩個獨立的 omap-root,分別用于記錄 omap 和 xattr构诚,均以 B+ 樹方式組織蚌斩。不同 object 的元數(shù)據(jù)組成相互獨立的樹,相比 Bluestore 每次 kv 操作都是在全局的 RocksDB 中進行范嘱,Seastore 中 kv 操作有對象級別的隔離送膳,預(yù)期性能會更好。

目前 LeafNode 對應(yīng)的 extent 長度 64KB(OMAP_LEAF_BLOCK_SIZE)丑蛤,InternalNode 長度 8KB(OMAP_INNER_BLOCK_SIZE),當新放入的 k-v 導(dǎo)致 node 超過這個閾值后則需要分裂肠缨、合并的一系列調(diào)整。

3. 關(guān)于 lba盏阶、backref

Seastore 提供了一個統(tǒng)一的邏輯地址空間晒奕,所有數(shù)據(jù)均是以 laddr 進行尋址;物理磁盤地址則抽象成 paddr名斟。

LBA Manager 負責(zé)記錄邏輯地址 laddr_t 到物理地址 paddr_t 的映射脑慧,Backref Manager 則相反。

Backref Manager 的存在是為了確認一個 paddr 是否仍在被使用砰盐,如果沒在使用則可以回收對應(yīng)物理空間闷袒。這主要是為了支持 Segment Backend 實現(xiàn)空間清理。對于 Random Block Backend 其主要用途是啟動階段遍歷 Backref tree岩梳,初始化 RBM 的 allocator囊骤。

LBA 和 Backref 都是以 FixedKVNode 作為 B+ 樹節(jié)點基類,他們的 InternalNode 的 value 都是 paddr_t冀值,用于沿樹逐層尋址到最終的 LeafNode也物。LBA 的 LeafNode 中的 value 記錄的是paddr(lba_map_val_t),作用就是記錄 laddr -> paddr 這樣一個 kv列疗;而 Backref 的 LeafNode 中的 value 則是 laddr(backref_map_val_t)滑蚯。

FixedKVTree 示例

二、Transaction 舉例

事務(wù)通過 Transaction Manager 管理抵栈,其內(nèi)部會調(diào)用 epm告材、cache、lba/backref manager 和 journal 等組件實現(xiàn)不同功能古劲。下面僅以寫入數(shù)據(jù)為例做簡要說明斥赋。

寫入數(shù)據(jù)的流程在 Transaction Manager 這一層主要是通過 TransactionManager::do_submit_transaction 實現(xiàn)數(shù)據(jù)的落盤。

do_submit_transaction涉及的主要步驟
  1. 寫新數(shù)據(jù)产艾。調(diào)用該接口前上層已經(jīng)分配好新的 extent疤剑,此時將 extent 數(shù)據(jù)落盤洛波。此處和 Bluestore 中的“先寫數(shù)據(jù)”模式一樣,都是寫到新地址骚露。
  2. prepare_record蹬挤。此處是將本次事務(wù)相關(guān)的元數(shù)據(jù)改動打包成 Record 格式,用來后續(xù)寫到 Journal 中棘幸。這里打包的數(shù)據(jù)分為兩類:完整的 extent 和 delta_info焰扳。完整的 extent 來自新分配元數(shù)據(jù) extent 場景,比如新分配的 root 節(jié)點或者 segment backend 下新分配的 lba 或 backref 的節(jié)點误续;delta_info 也有兩種吨悍,一種來自對現(xiàn)有元數(shù)據(jù)節(jié)點的改動,比如步驟一中為寫數(shù)據(jù)分配了新 extent蹋嵌,那么就需要在 LBA tree 中新增一個 k-v 記錄新分配的 extent 的 laddr->paddr育瓜,這時 LBA tree 中至少有一個結(jié)點發(fā)生了變動,這個變動會在此時被記錄成一個 delta 類型的信息栽烂,這就暫時避免了把 LBA 節(jié)點對應(yīng)的 extent 進行重寫/原地修改躏仇;另一種 delta_info則是 alloc 信息,用于記錄一個 paddr 已被分配腺办,這就避免了立即對 backref tree 進行改動焰手,而是交由由后臺程序?qū)⑦@個信息更新到 backref tree。omap 和 onode 的修改也是類似的處理方式怀喉,即避免馬上修改存在磁盤上的整個節(jié)點對應(yīng)的 extent书妻,而是追加一個 delta 信息到 journal。
  3. submit_record躬拢。這一步直接調(diào)用 journal 接口躲履,將上一步打包好的 Record 以追加方式落盤到 journal 區(qū)。
  4. complete_commit聊闯。比如步驟一中新分配的 extent 此時狀態(tài)設(shè)置為 CLEAN且在 Cache 中加入一個 backref entry(journal trim 時才會更新至 Backref tree)工猜,用于記錄相應(yīng) paddr 的使用信息。對于步驟 2 中產(chǎn)生了 delta_info 的 extent馅袁,例如相關(guān)的 LBA node域慷,則置為DIRTY狀態(tài)荒辕,等待 journal trimer 回收汗销。

三、Extent Placement Manager

1. 管理 extent

數(shù)據(jù)分類:epm 會將相同生命周期/類型數(shù)據(jù)放在一起抵窒。通過使用 category(data_category_t: DATA 或 METADATA)弛针,type(extent_types_t),hint(placement_hint_t: HOT, COLD, REWRITE)李皇,gen (rewrite_gen_t)這四個維度做數(shù)據(jù)分類削茁,同類數(shù)據(jù)在物理空間上盡量放在一起宙枷。不過這個目標實際主要是針對 Segment Backend,因為 Random Backend 只有 journal 和 data 兩個區(qū)域茧跋,對 data 區(qū)沒有做進一步細分慰丛。segment backend 因為將整個磁盤劃分成了多個 segment,可以做到將不同類型數(shù)據(jù)放到不同 segment瘾杭。其中 REWRITE 是因為空間清理時會 generation+1诅病,因此歸類成不同類別數(shù)據(jù),如果啟用了 cold segment粥烁,會有更多 generation贤笆。

EPM 中的數(shù)據(jù)分類

2. background trim

backgroud trim 分兩類:trim journal 和 clean space。

trim 分類

2.1 trim journal

journal 一直追加寫讨阻,而劃分給 journal 的磁盤大小是固定的芥永,所以需要 trim。trim 包括兩類:trim_dirty 和 trim_alloc钝吮。

trim_dirty 的過程就是通過rewrite_extent把 journal 中的 delta extent 信息寫到 extent 中埋涧。舉例來說,對于TransactionManager::do_submit_transaction中產(chǎn)生的對于 LBA node 的修改奇瘦,此時會發(fā)生一次完整的 extent 重寫:先分配一個新的元數(shù)據(jù) extent飞袋,將 journal 中的 delta 信息加上原 extent 中未改動的信息重新寫到新的 extent,當然链患,這個過程又需要一次TransactionManager::do_submit_transaction巧鸭。對于 Random Block backend,除 root 類節(jié)點外麻捻,重寫的 extent 都會放到 data 區(qū)纲仍,而 segment 略微不同,對于 LBA 和 Backref node贸毕,重寫時依然放到 journal 類的 segment 中郑叠,這個邏輯被封裝在 EPM 中。

trim_alloc 的過程就是將記錄在 journal 中的delta alloc 信息即物理磁盤空間分配信息更新到 Backref tree 中明棍。這是因為 transaction 在提交時并不會立刻把空間分配信息更新到 Backref Tree乡革,而是先記錄到 journal,由 trim_alloc 后臺更新到 Backref Tree摊腋。更新的過程也是通過再提交一次 transaction 完成沸版。

經(jīng)過 trim_dirty 和 trim_alloc 后,journal 中 記錄的 delta 信息便被清除了兴蒸。但對于 segment backend视粮,此時并不會回收 segment,回收放在 clean space 流程中橙凳,因為這時 journal 中可能還有 INLINE 類型的數(shù)據(jù)蕾殴。

2.2 clean space

顯而易見笑撞,對于 Segment backend 這種 LFS 式的空間管理,肯定需要一個 cleaner 來及時整理空間钓觉,消除空洞茴肥,此過程剛好也會處理掉journal 上的 INLINE 數(shù)據(jù)。對于 Random Block backend 則不需要這一步荡灾。

clean space 分六步:

  1. get_next_reclaim_segment:找出一個CLOSED狀態(tài)的且收益最大的 segment 準備回收炉爆。
  2. backref_manager.get_mappings:根據(jù)第一步中的 segment 的(物理)地址,查詢 Backref tree卧晓,得到 alive 的 extent芬首,這些 extents 需要挪到新地址。
  3. backref_manager.retrieve_backref_extents_in_range:收集處于待回收地址上的 Backref tree node逼裆,這些 extents 也需要挪到新地址郁稍。
  4. backref_manager.get_cached_backref_entries_in_range:收集內(nèi)存中記錄的處于待回收地址的 extents。執(zhí)行這一步是因為有些 alloc 信息位于 journal 還未更新到 Backref tree中胜宇。
  5. rewrite_extent 重寫步驟 2~4 中找到的有效 extent耀怜。數(shù)據(jù)寫入到新地址。
  6. release_segment桐愉。將 segment 標記為空閑财破,后續(xù)可被重新使用。
    以上的數(shù)據(jù)更新仍然會通過 submit transaction 方式進行从诲。

四左痢、后端磁盤管理

Seastore 中同時實現(xiàn)了兩種磁盤管理:segment 方式(LFS 方式,只能追加寫)和 Random Block 方式(可以隨機寫)系洛。

由于使用了 seastar 框架俊性,服務(wù)層面可以輕易擴展,一個 shard 即對應(yīng)一個 CPU 核描扯。但目前實現(xiàn)中一旦 mkfs 后 shard 數(shù)就無法再變化定页。

1. Segment Backend

Segment Backend 將磁盤分成多個 segment,寫入數(shù)據(jù)時在 segment 上追加寫入绽诚。目前有兩種實現(xiàn)典徊,分別支持傳統(tǒng) block 接口磁盤和 ZNS/SMR 磁盤。

1.1 傳統(tǒng)磁盤

傳統(tǒng)磁盤上 segment 布局

上圖中 tracker 用于記錄本 shard 上 segment 的狀態(tài)恩够,比如打開一個 segment 時需要將tracker 中對應(yīng)數(shù)據(jù)更新卒落,并落盤。不過該功能目前在代碼中未看到實際作用玫鸟。

每個 shard 管理一段區(qū)域导绷,這段區(qū)域被分成多個 segment,segment 大小默認64MB(seastore_segment_size)屎飘。

1.2. ZNS/SMR磁盤

這類磁盤除了不支持覆蓋寫外妥曲,讀寫接口和傳統(tǒng)磁盤一樣,但有一套額外的 ioctl 接口管理磁盤钦购,這套管理接口以 zone 為單位檐盟,目前 ZBDSegmentManager 實現(xiàn)中是一個 segment 等價一個 zone,zone 大小則通過磁盤管理接口讀出押桃。

支持追加寫的磁盤 segment 布局

2. Random Block Backend

Random Block Backend 在命名上直接使用了NVMeBlockDevice葵萎,可以看出 Seastore 對于 HDD 只建議使用 Segment Backend。

RBMDevice磁盤布局

五唱凯、Journal

關(guān)于磁盤管理最后還有一部分是關(guān)于 journal羡忘。為了支持事務(wù),journal 不可避免磕昼。Bluestore 中沒有明顯的 journal 是因為先寫數(shù)據(jù)卷雕,再將元數(shù)據(jù)存到 RocksDB 中,最終是由 RocksDB 提供了對事務(wù)的保證票从,實際上Bluestore 的 wal 分區(qū)即為 RocksDB 的 journal漫雕。

Seastore 中的兩種 Backend 各自實現(xiàn)了一種 Journal:CircularBoundedJourna和SegmentedJournal。SegementedJournal 寫滿后會分配新的 segment 繼續(xù)寫峰鄙,通過 trim 和 clean 來回收空間浸间,而CircularBoundedJournal則是將 journal 分區(qū)當做 ring buffer 使用。

1. SegmentedJournal

SegmentedJournal 組件
  • JournalTrimmer:負責(zé) journal 清理吟榴,由 epm 調(diào)用
  • RecordSubmitter:以 Record 格式管理數(shù)據(jù)
  • SegmentAllocator:一個 segment 用完后分配新的 segment
  • SegmentSeqAllocator:新 segment 需要新的 seq
  • SegmentGroupManager:負責(zé)除 record submit 以外的 IO

2. CircularBoundedJournal

CirularBoundedJournal 組件
  • JournalTrimmer:負責(zé) journal 清理魁蒜,由 epm 調(diào)用
  • RecordSubmitter:以 Record 格式管理數(shù)據(jù)
  • CircularJournalSpace:負責(zé)除 record submit 以外的 IO,管理 write_pointer 等信息

總結(jié)

以上對 Seastore 的部分組件進行了簡要介紹吩翻,從設(shè)計上可以看出確實針對上一代 Bluestore 中的問題做了針對性處理梅惯,且引入了 LSF 和 RTC 模型,但目前 Seastore 仍不支持 SPDK仿野,這也算一個遺憾了铣减。DPDK 的話通過 seastar 應(yīng)該能直接使用,但 SPDK 功能 seastar 還未集成脚作。根據(jù)社區(qū)開發(fā)者的說法是希望等 seastar 完成對 SPDK 的封裝葫哗,而不是在 Seastore 中支持 SPDK。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末球涛,一起剝皮案震驚了整個濱河市劣针,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌亿扁,老刑警劉巖捺典,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異从祝,居然都是意外死亡襟己,警方通過查閱死者的電腦和手機引谜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擎浴,“玉大人员咽,你說我怎么就攤上這事≈ぃ” “怎么了贝室?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長仿吞。 經(jīng)常有香客問我滑频,道長,這世上最難降的妖魔是什么唤冈? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任峡迷,我火速辦了婚禮,結(jié)果婚禮上务傲,老公的妹妹穿的比我還像新娘凉当。我一直安慰自己,他們只是感情好售葡,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布看杭。 她就那樣靜靜地躺著,像睡著了一般挟伙。 火紅的嫁衣襯著肌膚如雪楼雹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天尖阔,我揣著相機與錄音贮缅,去河邊找鬼。 笑死介却,一個胖子當著我的面吹牛谴供,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播齿坷,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼桂肌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了永淌?” 一聲冷哼從身側(cè)響起崎场,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎遂蛀,沒想到半個月后谭跨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年螃宙,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛮瞄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡污呼,死狀恐怖裕坊,靈堂內(nèi)的尸體忽然破棺而出包竹,到底是詐尸還是另有隱情燕酷,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布周瞎,位于F島的核電站苗缩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏声诸。R本人自食惡果不足惜酱讶,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望彼乌。 院中可真熱鬧泻肯,春花似錦、人聲如沸慰照。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毒租。三九已至稚铣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間墅垮,已是汗流浹背惕医。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留算色,地道東北人抬伺。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像灾梦,于是被迫代替她去往敵國和親峡钓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容