這篇文章將深入NVMe over Fabric內部,探究其設計思路及其規範下IO的傳輸過程。對於NVMe over Fabrics協議來說,要解決下麵幾個問題:
- 提供對於不同互聯透明的訊息和資料的封裝格式;
- 將NVMe進行操作所需要的介面方式對映到網際網路絡;
- 解決網際網路絡的節點發現、多路徑等互聯引入的新問題。
針對資料封裝,協議定義了一整套封裝方案。與傳統的NVMe協議相比,這套封裝方案針對互聯做了一些調整和適配。NVMe定義了一套非同步的由軟體驅動硬體執行相應動作的非同步操作機制,傳送和完成包僅僅攜帶必要的描述,而真正的資料和SGL描述符都是放在記憶體中並且由硬體透過DMA方式取得的。
這是基於PCIe的DMA操作延遲很短(1us)的前提而設計的。在互聯協議中,節點之間的互動時間大大增加,為了降低兩個節點之間不必要的互動,傳送請求可以直接攜帶附加的資料或SGL描述符,完成請求也可以攜帶需要回傳的資料,節約了兩者之間互動的負擔。
與此同時,為了節約系統互動,在NVMe over Fabrics協議中,完成佇列沒有使用流控機制,因此需要接收端有足夠容納所有已經發出去的命令的完成佇列空間,來容納所有完成請求。一次IO的傳輸過程如下圖所示:
- Initiator端驅動程式封裝傳送請求並派發給硬體;
- Initiator端硬體將傳送請求發到Target端的傳送佇列;
- Target端控制器處理完成IO請求,並準備出來完成請求派發給硬體;
- Target端硬體將完成請求發到Initiator端的接收佇列。
由於傳送請求和完成請求可以直接攜帶資料,從而降低互聯中消耗的互動時間。如果不需要請求中攜帶資料,也可以由Target端在過程中直接從Initiator端獲得相應的資料,如下圖所示。
透過上述機制,NVMe over Fabrics協議實現了對於NVMe協議的命令和資料傳輸的擴充套件。普通的NVMe命令都可以透過這套機制對映,NVMe的標準命令搖身一變,就成為了互聯協議的命令。不過還是有一些場景是需要特殊考慮的,為了支援這些場景,協議擴充套件了NVMe命令,增加了與互聯相關的5個命令:
- Connect
- Property Get/ Set
- Authentication Send/ Receive
Authentication Send/Receive主要用於做Initiator端和Target端的安全協議的傳遞,服從SPC-4。下麵重點說一說Connect和Property Get/ Set。
在NVMe over Fabrics協議中,約定每個傳送佇列都與一個接收佇列對應,不允許多個傳送佇列使用同一個接收佇列。傳送接收佇列對是透過Connect命令來建立的。Connect命令攜帶有Host NQN,NVM Subsystem NQN和Host Identifier資訊,並且可以指定連線到一個靜態的控制器,或者連線到一個動態的控制器。
一個主機可以透過不同的Host NQN或不同的Fabric Port建立到一個NVM Subsystem的多重連線。這種靈活性賦予了NVMe over Fabrics極大的靈活性。按照協議規定,同一個控制器的所有傳送接收佇列對既可以共享底層的互聯通道,也可以分別獨佔一格底層互聯通道,方便根據傳輸層的特點來進行靈活的選擇。
在NVMe協議中,控制器是一個代表與主機進行溝通的介面物體。由於PCIe協議是一種樹狀拓撲結構,因此一旦控制器所處的PCIe Port定下來後,介面所關聯的控制器就完全定下來了。而對於NVMe over Fabrics協議來說,一個Fabric的Port可以嵌入多個控制器,因此根據需要不同,可以選擇實現靜態控制器或動態控制器。
動態控制器是一種簡單的模型,適用於對主機具有相同的服務特性的需求。靜態控制器則適用於有不同需要的場景,Initiator可以查詢瞭解一個Fabric Port內部包含的靜態控制器各自的能力,然後選擇連線到指定的控制器以滿足自身的需要。
在經典的NVMe協議中,PCIe空間的BAR0(BAR1)描述了一段記憶體空間用於對控制器進行基本的暫存器級別的配置。由於Fabrics結構沒有等效的實現,因此NVMe over Fabrics協議定義了Property Get/ Set分別表示對於控制器端的暫存器讀取和寫入動作。
至此,NVMe的標準操作就完全被準確和高效地對映成網際網路絡所對應的使用方式了。為了能滿足網際網路絡的發現機制,NVMe over Fabrics協議定義了發現服務,用於讓Initiator主動發現NVM Subsystem和對應的可訪問的名字空間。這個服務還同時用於支援多路徑功能。該功能依賴於一個特殊的配置成支援發現服務的NVMe Subsystem。Initiator可以連線到該伺服器並使用Discovery Log Page命令來獲取可用的資源。
與NVMe over Fabrics協議一同釋出的,還有一份在Linux平臺上實現的基於RDMA和FC傳輸層的NVMe協議的Initiator和Target端的參考程式碼。這份程式碼不僅僅包含了協議的驅動實現,也包含了對應的CLI工具和Linux OS整合支援。相信對整個生態圈來說這會是一個良好的開端。
推薦閱讀: