DAOS 分散式非同步物件儲存|資料平面

debugzhang發表於2021-04-07

DAOS 通過兩個緊密整合的平面進行運轉。資料平面處理繁重的運輸操作,而控制平面負責程式編排和儲存管理,簡化資料平面的操作。

模組介面

I/O 引擎支援一個模組介面,該介面允許按需載入伺服器端程式碼。每個模組實際上都是一個庫,由 I/O 引擎通過 dlopen 動態載入。模組和 I/O 引擎之間的介面在 dss_module 資料結構中定義。

每個模組應指定:

  • 模組名
  • daos_module_id 中的模組識別符號
  • 特徵位掩碼
  • 一個模組初始化和銷燬函式

此外,模組還可以選擇配置:

  • 在整個堆疊啟動並執行後呼叫的配置和清理函式
  • CART RPC 處理程式
  • dRPC 處理程式

執行緒模型與 Argobot 整合

I/O 引擎是一個多執行緒程式,使用 Argobot 進行非阻塞處理。

預設情況下,每個 Target 都會建立一個 main xstream 和 no offload xstreams。offload xstream 的實際數量可以通過 daos_engine 命令列引數進行配置。此外,還建立了一個額外的 xstream 來處理傳入的後設資料請求。每個 xstream 都繫結到一個特定的 CPU 核心。main xstream 接收來自客戶端和其他伺服器的 Target 傳入請求。一個特定的 ULT (User Level Thread) 會在網路和 NVMe I/O 操作方面提供幫助。

Thread-local Storage (TLS)

每個 xstream 分配的私有儲存可以通過 dss_tls_get() 函式進行訪問。

註冊時,每個模組可以指定一個模組金鑰,該金鑰的資料結構大小將由 TLS 中的每個 xstream 進行分配。

dss_module_key_get() 函式的作用是:返回特定註冊模組金鑰的資料結構。

Incast Variable 整合

DAOS 使用 IV (incast variable) 在單個 IV 名稱空間(組織結構為樹)下的伺服器之間共享值和狀態。樹的根節點稱為 IV leader,伺服器可以是葉子節點也可以是非葉子節點。

每個伺服器都維護自己的 IV 快取。在獲取過程中,如果本地快取不能完成請求,它會將請求轉發給其父快取,直到到達根快取 (IV leader)。對於更新操作,伺服器首先更新它的本地快取,然後轉發到它的父快取,直到到達根快取,然後將更改傳播到其他的伺服器。

IV 名稱空間是屬於每個 Pool 的,在 Pool 連線期間建立,在 Pool 斷開連線期間銷燬。

要使用 IV,每個使用者需要在 IV 名稱空間下注冊自己以獲得識別符號,然後使用者將使用這個 ID 來獲取或更新自己在 IV 名稱空間下的 IV 值。

dRPC 伺服器

I/O 引擎包括一個 dRPC 伺服器,它監聽給定 Unix Domain Socket 上的活動。

有關 dRPC 的基礎知識以及 Go 和 C 中的底層 API 的更多詳細資訊,請參閱 dRPC Documentation

dRPC 伺服器定期輪詢傳入的客戶端連線和請求。它可以通過 struct drpc_progress_context 物件同時處理多個客戶端連線,該物件管理監聽 Socket 的 struct drpc 物件以及任何活動的客戶端連線。

伺服器在 xstream 0 自己的 ULT (User Level Thread) 中迴圈執行。dRPC Socket 已設定為非阻塞的,並且使用無超時輪詢。這允許伺服器在 ULT 中執行,而不是在自己的 xstream 中執行,預計該通道的流量相對較低。

dRPC 程式

drpc_progress 表示 dRPC 伺服器迴圈的一次迭代。其工作流程如下:

  1. 在監聽 Socket 和任何開啟的客戶端連線上同時進行超時輪詢。
  2. 如果在客戶端連線上看到任何活動:
    1. 如果資料已輸入:呼叫 drpc_recv 處理輸入的資料。
    2. 如果客戶端已斷開連線或連線被破壞:釋放 struct drpc 物件並將其從 drpc_progress_context 中刪除。
  3. 如果在監聽器上發現任何活動:
    1. 如果有新的連線進入:呼叫 drpc_accept 並將新的 struct drpc 物件新增到 drpc_progress_context 中的客戶端連線列表中。
    2. 如果有錯誤:將 -DER_MISC 返回給呼叫者。I/O 引擎中會記錄該錯誤,但不會中斷 dRPC 伺服器迴圈。在監聽器上獲取到錯誤是意外情況。
  4. 如果沒有看到任何活動,則將 -DER_TIMEDOUT 返回給呼叫者。這純粹是為了除錯目的,實際上,I/O 引擎會忽略此錯誤程式碼,因為缺少活動實際上並不是一種錯誤。

dRPC 處理程式註冊

單個 DAOS 模組可以通過註冊一個或多個 dRPC 模組 ID 的處理函式來實現對 dRPC 訊息的處理。

註冊處理程式很簡單。在 dss_server_module 的欄位 sm_drpc_handlers 中,靜態分配一個 struct dss_drpc_handler陣列,該陣列的最後一項為零,以指示列表的結尾。將欄位設定為 NULL 表示沒有要註冊的處理程式。當 I/O 引擎載入 DAOS 模組時,它將自動註冊所有 dRPC 處理程式。

注意:

  • dRPC 模組 ID 與 DAOS 模組 ID 不同。
  • 這是因為給定的 DAOS 模組可能需要註冊多個 dRPC 模組 ID,具體數量取決於 DAOS 模組所涵蓋的功能。
  • dRPC 模組 ID 必須是系統範圍內唯一的,並且列在一箇中心標頭檔案 `src/include/daos/drpc_modules.h 中。

dRPC 伺服器使用函式 drpc_hdlr_process_msg 來處理傳入的訊息。此函式檢查傳入訊息的模組 ID,搜尋處理程式。

  • 如果找到處理程式,則執行該處理程式,並返回 Drpc_Response
  • 如果找不到,它將生成自己的 Drpc_Response,指示模組 ID 未註冊。

相關資訊

GitHub: https://github.com/storagezhang

Emai: debugzhang@163.com

華為雲社群: https://bbs.huaweicloud.com/blogs/255571

DAOS: https://github.com/daos-stack/daos

本文翻譯自 https://github.com/daos-stack/daos/blob/master/src/control/README.md

相關文章