DAOS 分散式非同步物件儲存|儲存模型
阿新 • • 發佈:2021-04-02
# 概述
![abstractions](https://img2020.cnblogs.com/blog/1425766/202104/1425766-20210401213732015-190629535.png)
DAOS Pool 是分佈在 Target 集合上的儲存資源預留。分配給每個 Target 上的 Pool 的實際空間稱為 Pool Shard。
分配給 Pool 的總空間在建立時確定,後期可以通過調整所有 Pool Shard 的大小(在每個 Target 專用的儲存容量限制內)或跨越更多 Target(新增更多 Pool Shard)來隨時間擴充套件。
Pool 提供了儲存虛擬化,是資源調配和隔離的單元。DAOS Pool 不能跨多個系統。
一個 Pool 可以承載多個稱為 DAOS Container 的事務物件儲存。每個 Container 都是一個私有的物件地址空間,可以對其進行事務性修改,並且獨立於儲存在同一 Pool 中的其他 Container。Container 是快照和資料管理的單元。屬於 Container 的 DAOS 物件可以分佈在當前 Pool 的任何一個 Target 上以提高效能和恢復能力,並且可以通過不同的 API 訪問,從而高效地表示結構化、半結構化和非結構化資料。
下表顯示了每個 DAOS 概念的目標可伸縮性級別:
| DAOS 概念 | 可伸縮性(數量級) |
| --------- | ------------------------------- |
| System | $10^5$ Servers and $10^2$ Pools |
| Server | $10^1$ Targets |
| Pool | $10^2$ Containers |
| Container | $10^9$ Objects |
# DAOS Pool
Pool 由唯一的 Pool UUID 標識,並在稱為 Pool 對映的持久版本控制列表中維護 Target 成員身份。成員資格是確定的和一致的,成員資格的變更是按順序編號的。Pool 對映不僅記錄活躍 Target 的列表,還以樹的形式包含儲存拓撲,用於標識共享公共硬體元件的 Target。例如,樹的第一級可以表示共享同一主機板的 Target,第二級可以表示共享同一機架的所有主機板,最後第三級可以表示同一機房中的所有機架。
該框架有效地表示了層次化的容錯域,然後使用這些容錯域來避免將冗餘資料放置在發生相關故障的 Target 上。在任何時候,都可以將新 Target 新增到 Pool 對映中,並且可以排除失敗的 Target。此外,Pool 對映是完全版本化的,這有效地為對映的每次修改分配了唯一的序列,特別是對於失敗節點的刪除。
Pool Shard 是永久記憶體的預留,可以選擇與特定 Target 上 NVMe 預先分配的空間相結合。它有一個固定的容量,滿了就不能執行。可以隨時查詢當前空間使用情況,並報告 Pool Shard 中儲存的任何資料型別所使用的總位元組數。
一旦 Target 失敗並從 Pool 對映中排除,Pool 中的資料冗餘將自動線上恢復。這種自愈過程稱為重建。重建進度定期記錄在永久記憶體中儲存的 Pool 中的特殊日誌中,以解決級聯故障。新增新 Target 時,資料會自動遷移到新新增的 Target,以便在所有成員之間平均分配佔用的空間。這個過程稱為空間再平衡,使用專用的永續性日誌來支援中斷和重啟。
Pool 是分佈在不同儲存節點上的一組 Target,在這些節點上分佈資料和元資料以實現水平可伸縮性,並使用複製或糾刪碼 (erasure code) 確保永續性和可用性。
建立 Pool 時,必須定義一組系統屬性以配置 Pool 支援的不同功能。此外,使用者還可以定義將持久儲存的屬性。
Pool 只能由經過身份驗證和授權的應用程式訪問。DAOS 支援多種安全框架,例如 NFSv4 訪問控制列表或基於第三方的身份驗證 (Kerberos)。連線到 Pool 時強制執行安全性檢查。成功連線到 Pool 後,將嚮應用程式程序返回連線上下文。
如前文所述,Pool 儲存許多不同種類的永續性元資料,如 Pool 對映、身份驗證和授權資訊、使用者屬性、特性和重建日誌。這些元資料非常關鍵,需要最高級別的恢復能力。因此,Pool 的元資料被複制到幾個來自不同高階容錯域的節點上。對於具有數十萬個儲存節點的非常大的配置來說,這些節點中只有很小的一部分(大約幾十個)執行 Pool 元資料服務。在儲存節點數量有限的情況下,DAOS 可以依賴一致性演算法來達成一致,在出現故障時保證一致性,避免腦裂。
要訪問 Pool,使用者程序應該連線到 Pool 並通過安全檢查。一旦授權,Pool 就可以與任何或所有對等應用程式程序(類似 `openg()` POSIX 擴充套件)共享(通過 `local2global()` 和 `global2local()` 操作)連線。這種集體連線機制有助於在資料中心上執行大規模分散式作業時避免元資料請求風暴。當發出連線請求的原始程序與 Pool 斷開連線時,Pool 連線將被登出。
# DAOS Container
Container 代表 Pool 中的物件地址空間,由 Container UUID 標識。
下圖顯示了使用者(I/O 中介軟體、特定領域的資料格式、大資料或 AI 框架等)如何使用 Container 來儲存相關資料集:
![containers](https://img2020.cnblogs.com/blog/1425766/202104/1425766-20210401213754183-1459178355.png)
與 Pool 一樣,Container 可以儲存使用者屬性。Container 在建立時必須傳遞一組屬性,以配置不同的功能,例如校驗和。
要訪問 Container,應用程式必須首先連線到 Pool,然後開啟 Container。如果應用程式被授權訪問 Container,則返回 Container 控制代碼,它的功能包括授權應用程式中的任何程序訪問 Container 及其內容。開啟程序可以與所有對等程序共享此控制代碼。它們的功能在 Container 關閉時被撤銷。
Container 中的物件可能具有不同的模式,用於處理資料分佈和 Target 上的冗餘,定義物件模式所需的一些引數包括動態或靜態條帶化、複製或糾刪碼。Object 類定義了一組物件的公共模式屬性,每個 Object 類都被分配一個唯一的識別符號,並在 Pool 級別與給定的模式相關聯。一個新的 Object 類可以在任何時候用一個可配置的模式來定義,這個模式在建立之後是不可變的(或者至少在屬於這個類的所有物件都被銷燬之前)。
為了方便起見,在建立 Pool 時,預設情況下會預定義幾個最常用的 Object 類:
| Object Class (RW = read/write, RM = read-mostly | Redundancy | Layout (SC = stripe count, RC = replica count, PC = parity count, TGT = target |
| :---------------------------------------------- | :----------- | :----------------------------------------------------------- |
| Small size & RW | Replication | static SCxRC, e.g. 1x4 |
| Small size & RM | Erasure code | static SC+PC, e.g. 4+2 |
| Large size & RW | Replication | static SCxRC over max #targets) |
| Large size & RM | Erasure code | static SCx(SC+PC) w/ max #TGT) |
| Unknown size & RW | Replication | SCxRC, e.g. 1x4 initially and grows |
| Unknown size & RM | Erasure code | SC+PC, e.g. 4+2 initially and grows |
如下所示,Container 中的每個物件都由一個唯一的 128 位物件地址標識。物件地址的高 32 位保留給 DAOS 來編碼內部元資料,比如 Object 類。剩下的 96 位由使用者管理,在 Container 中應該是唯一的。只要保證唯一性,棧的上層就可以使用這些位來編碼它們的元資料。DAOS API 為每個 Container 提供了 64 位可伸縮物件 ID 分配器。應用程式要儲存的物件 ID 是完整的 128 位地址,該地址僅供一次性使用,並且只能與單個物件模式相關聯。
```
<---------------------------------- 128 bits ---------------------------------->
--------------------------------------------------------------------------------
|DAOS Internal Bits| Unique User Bits |
--------------------------------------------------------------------------------
<---- 32 bits ----><------------------------- 96 bits ------------------------->
```
Container 是事務和版本控制的基本單元。所有的物件操作都被 DAOS 庫隱式地標記為一個稱為 epoch 的時間戳。DAOS 事務 API 允許組合多個物件更新到單個原子事務中,並基於 epoch 順序進行多版本併發控制。所有版本更新都可以定期聚合,以回收重疊寫入所佔用的空間,並降低元資料複雜性。快照是一個永久引用,可以放置在特定的 epoch 上以防止聚合。
Container 元資料(快照列表、開啟的控制代碼、物件類、使用者屬性、屬性和其他)儲存在永續性記憶體中,並由專用 Container 元資料服務維護,該服務使用與父元資料 Pool 服務相同的複製引擎或自己的引擎,這在建立 Container 時是可配置的。
與 Pool 一樣,對 Container 的訪問由 Container 控制代碼控制。要獲取有效的控制代碼,應用程式程序必須開啟 Container 並通過安全檢查。然後,可以通過 Container 的 `local2global()` 和 `global2local()` 操作與其他對等應用程式程序共享此控制代碼。
# DAOS Object
為了避免傳統儲存系統常見的擴充套件問題和開銷,DAOS 有意將物件簡化,不提供型別和架構之外的預設物件元資料。這意味著系統不維護時間、大小、所有者、許可權,甚至不跟蹤開啟者。
為了實現高可用性和水平伸縮性,DAOS 提供了許多物件模式(複製/糾刪碼、靜態/動態條帶化等)。模式框架是靈活的,並且易於擴充套件,以允許將來使用新的自定義模式型別。模式佈局是在物件識別符號和 Pool 對映開啟的物件上通過演算法生成的。通過在網路傳輸和儲存期間使用校驗和保護物件資料,確保了端到端的完整性。
可以通過不同的 API 訪問 DAOS 物件:
- **Multi-level key-array API** 是具有區域性性特徵的本機物件介面。金鑰分為分發金鑰 (dkey) 和屬性金鑰 (akey)。dkey 和 akey 都可以是可變長度的型別(字串、整數或其它複雜的資料結構)。同一 dkey 下的所有條目都保證在同一 Target 上並置。與 akey 關聯的值可以是不能部分修改的單個可變長度值,也可以是固定長度值的陣列。akeys 和 dkey 都支援列舉。
- **Key-value API** 提供了一個簡單的鍵和可變長度值介面。它支援傳統的 put、get、remove 和 list 操作。
- **Array API** 實現了一個由固定大小的元素組成的一維陣列,該陣列的定址方式是 64 位偏移定址。DAOS 陣列支援任意範圍的讀、寫和 punch 操作。
# 相關資訊
> GitHub: https://github.com/storagezhang
>
> Emai: [email protected]
>
> 華為雲社群: https://bbs.huaweicloud.com/blogs/253715
>
> DAOS: https://github.com/daos-stack/daos
>
> 本文翻譯自 https://daos-stack.github.io/overview/