動機和背景
存儲計算&IO棧
存儲計算可以降低數據移動開銷并充分利用設備內帶寬,相比于特定計算加速,通用存儲計算框架可以允許用戶自定義卸載到存儲設備的計算邏輯。然而大部分工作都關注于控制存儲設備的接口和用戶空間,但是缺乏對主機側計算&存儲資源的充分利用。IO棧是管理存儲器的的基本組件,包括設備驅動、塊接口層、文件系統,目前一些用戶空間IO庫(如SPDK)有效降低了延遲,但是io棧仍然不可或缺。這是因為1)大部分引用采用POSIX接口需要IO棧的兼容性;2)IO棧提供了包括page cache、文件系統等多種功能模塊。而用戶空間IO庫只提供原始數據傳輸功能;3)IO棧可以使得不同用戶、應用充分共享存儲設備。
主機-設備協作
作者通過測試,發現不同特征的應用,對主機/設備具有不同的適應性。例如,在主機/設備側分別運行Stat64和stat32。stat64在主機側運行更快,stat32在設備側運行更快。另外,一個應用的不同運行階段,也具有不同的特征。例如使用warm page-cache策略運行stat64,發現無緩存時在設備上更快,緩存越多主機端越快。
eBPF
eBPF是一種內核中的虛擬機,允許用戶在不修改內核源碼的情況下運行一段代碼,其運行過程如下圖所示。因為eBPF可以提供硬件無關的字節碼格式,其可用于構建ISC運行時。然而,eBPF也存在一些問題:1)eBPF的靜態校驗器過于嚴格;2)缺乏指針訪問和動態長度循環機制。因此,需要對eBPF進行擴展以更好的支持存儲計算。
設計方案
λ-IO通過擴展vanilla-IO框架,支持將計算動態卸載到內核/設備中進行計算。
它由三部分組成,如下圖所示:
λ運行時:包括λ內核運行時和λ設備運行時,用于提供λ請求的計算接口
請求分發器:用于評估效率,將任務自動分發給設備/內核執行。
λ-API
λ-API繼承了vanilla IO的open/close/read/write接口,并擴展了λ_load/ λ _read/λ_write接口用于應用提交計算卸載請求。其中,λ函數是計算方法的實體,load_ λ用于將λ函數編譯為eBPF代碼;而open_λ/close_ λ:與vanilla中的定義保持一致,可以使用vanilla/ λ擴展函數。
pread_λ和pwrite_λ用于執行計算卸載,其中pread_λ表示以fd,offset,length表示的文件內容作為入參執行λ_id表示的λ函數,并將返回結果寫到buf中。其執行步驟為:1)將文件數據作為輸入數據加載到內存buffer中;2)為輸出數據分配buffer空間;3)執行λ函數;4)將輸出buffer的數據拷貝到用戶分配的buffer中。pwrite_λ與pread_λ類似,但是其輸入、輸出參數相反。
λ運行時
λ運行時是執行load_ λ, pread_ λ, pwrite _λ的核心,它的實現具有兩方面的關鍵挑戰:1)計算:內核/設備的λ運行時都需要保存、執行計算函數;2)數據:λ運行時需要保存、訪問文件數據和用戶應用信息。
作者通過允許sBPF對BPF代碼執行動態驗證,使能指針、循環將eBPF擴展為sBPF。其中,指針訪問的修改包括在JIT中增加指針地址檢測代碼,讓sBPF可以在運行中檢查指針,若指針未落在輸入buffer中,則停止執行并返回錯誤碼。另外,作者表示,所有循環都包括一個offset為負的跳轉指令,因此sBPF使用了一個動態的后跳計數器,并限制后跳的執行次數,以避免死循環的發生。作者之后對其安全性進行了分析,并表示雖然增加了功能,但由于檢驗嚴格,并不會增加eBPF的安全性風險。
關于數據問題,主要是設備/內核的一致性訪問問題。對于λ內核運行時,作者使用內核中通用的kernel_write和kernel_read訪問文件,讓內核管理頁緩存和文件一致性,另外為了減少讀寫文件引起的大規模內存搬移,作者提出kernel_mmap進行內存映射解決這個問題。
對于設備運行時的文件一致性訪問,作者提出,雖然由于設備對文件語義不可知,需要準確的物理地址,但是文件的IOCTL中由FIEMAP和FIBMAP用于提取元數據中的物理地址,可以解決設備的文件訪問問題。而一致性問題包括內核-用戶空間一致性和主機-設備一致性兩方面,對于內核-用戶空間一致性問題,由于采用的是標準syscall接口,內核可以管理一致性,而主機設備一致性問題則通過1)使用讀寫鎖避免同時訪問帶來的一致性風險;2)在分發λ請求前,將請求數據文件相關的臟頁刷入設備并清空緩存,可以解決其一致性問題。
請求分發器
請求分發器的目的是通過預測主機、設備對某個任務的執行時間,選擇其中更快的那個進行分發,以達到更快、更高效的目的。為了評估執行時間,需要對執行時間進行建模。
為此,首先對相關變量進行符號表示如下表。
D | 存儲器中內容大小 |
Bs | 存儲介質-控制器傳輸帶寬 |
Bd | 主機-設備傳輸帶寬 |
Bh | 主機計算的等效帶寬 |
α | 輸入/輸出長度比值 |
β | 設備/主機計算吞吐量比值 |
之后,對主機、設備端分別建模其執行時間,當不考慮緩存時,使用pread_λ在內核、設備端的執行時間如下公式所示
。當考慮緩存時,則其形式變為如下
。而pwrite_λ的執行時間則為
。
評估
評估環境
本文中在一個配備4核8線程的I7-7700@3.6GHz,16GB DDR4內存的電腦上運行內核為linux 5.10.21的Ubuntu20.04LTS操作系統進行測試。存儲計算設備則采用Xilinx Zynq Ultrascale+ ZU17EG搭配2GB內存核64GBNand Flash。測試負載包括Stat64, Stat32, KNN, Grep, Bitmap。評估對比對象包括了1)Buffer IO(B):默認的vanilla IO;2)DirectIO(I):類似Buffer IO,但開啟O_DIRECT;3)Mmap(M):將數據文件讀入用戶空間,避免內核數據拷貝;4)λ-IO kernel(K):使用內核計算的λ-IO;5)λ-IO device(D):使用設備計算的λ-IO;6)λ-IO(λ):啟用請求分發的λ-IO。
單應用性能測試
對單個應用的性能分析,作者將執行時間細分為三部分:IO/計算/其他。首先對比λ-IO Device(d)和Buffer IO(B)。可以發現,d相比B,Stats64, KNN, Grep, Bitmap分別提升23.24%, 10.82%, 87.13%, 60.15%。這是由于主機端IO時間占比超過92.04%。另外,由于設備僅有4核4線程,而主機發送請求為8線程,因此出現了請求排隊現象。在stat32中d執行時間超過B 6.65倍 ,是由于64位eBPF對32位程序執行效率不高導致的。
之后作者對比了λ-Io Kernel(k)核vanilla-IO(B)之間的性能差異,并發現二者性能基本相同。λ-IO由于sBPF增加了運行時動態檢驗,帶來了部分額外開銷,但是又因為kernel_mmap避免了內存復制的開銷,二者基本相互抵消。
最后作者對比了λ-IO不同模式之間的性能差異,并發現,引入請求分配器的λ-IO在每項測試中的性能都基本相當于k、d模式下更快的那一個,并且通過對比,可以發現請求分配器帶來的額外開銷約為4.98%。
多應用評估
作者通過同時運行5種負載之二評估同時運行不同負載的性能差別。發現,當運行項包括stat32時,Stat32被分發到主機,另一個分發到設備運行,因此λ-IO性能提升2.19倍,其他情況下λ-IO也有1.98倍的整體性能提升。
敏感性分析
作者接著進行了敏感性分析。首先是數據集大小敏感性,作者使用stat64測試為例,發現在緩存>數據集大小時,由于避免了IO瓶頸,內核性能最佳,當緩存≈數據大小時,頁緩存的影響變小,λ-IO性能更好,當數據>緩存大小時,λ-IO由于高效分發請求,比其他對照組快1.28-1.60倍不等。
接著是熱啟動敏感性,作者發現Buffer-IO在熱啟動下性能比冷啟動更好一些,但是λ-IO性能仍是Buffer-IO的4.05倍。
之后作者分析了請求分發器的預測周期和預測長度的敏感性,發現,當預測周期超過200后,性能基本不發生改變,因此將默認預測周期設為200,而對于預測長度,可以看到隨著預測長度增加,執行時間迅速增長,因此默認預測長度被設為5。
對于緩存大小和線程數量,可以看到大部分應用對緩存大小不敏感,且大部分應用隨著線程數增長而增長,并在4線程時基本觸頂。
BPF開銷
通過對比運行時間,作者表示sBPF相比eBPF,循環檢查對內核/設備增加不超過2.44%和10.09%的開銷,加上指針檢查,sBPF對內核/設備引入不超過16.96%和22.68%的額外開銷。
Spark SQL
作者最后將spark SQL移植適配λ-IO,并測試了其在TPC-H負載下的真實性能表現。對比發現在buffer-IO模式下,IO占用了27.02%-60.41%的總時間,λ-IO Kernel與buffer-IO類似,λ-IO將任務分發至設備,提升最高81.55%的性能,暖啟動后λ-IO比B/K/D分別提升2.15、2.16、1.51倍,在CPU密集型任務中Q20任務在D中執行時間比K少18.45%。
總結
在本文中提出了λ-IO,其擴展了Linux IO,使計算能夠卸載到主機內核和設備。作者在真實的軟硬件環境中實現并評估了λ-IO,其顯示出顯著的性能提升。
-
Linux
+關注
關注
87文章
11506瀏覽量
213425 -
BPF
+關注
關注
0文章
26瀏覽量
4321 -
IO棧
+關注
關注
0文章
2瀏覽量
596
原文標題:λ-IO:存儲計算下的IO棧設計
文章出處:【微信號:SSDFans,微信公眾號:SSDFans】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
IO如何實現

緩存和RAID如何提高IO
如何使用io.Reader和io.Writer接口在程序中實現流式IO
現代異步存儲訪問API探索:libaio、io_uring和SPDK

亞信電子推出全新IO-Link設備軟件協議棧解決方案

亞信電子推出全新IO-Link設備軟件協議棧解決方案

遠程IO與分布式IO的區別
初識IO-Link及IO-Link設備軟件協議棧

亞信電子于IAS 2024展出最新IO-Link主站&設備軟件協議棧解決方案

評論