淺談分佈式存儲中的網絡通信

作者 | 火尉子

責編 | Carol

封圖 | CSDN 下載自視覺中國

在各行各業數字化轉型深入的當下,數據呈爆炸式增長。面對海量數據的存儲需求,分佈式存儲顯然在架構上有着天然優勢,但在這波數據洪流之中也面臨着性能上的全新挑戰。

由於分佈式存儲的工作原理是將各個存儲節點使用網絡互聯的方式構建爲集羣,向外部提供更加可靠的高性能服務,因此可以說分佈式存儲本質上是一種網絡存儲,其性能在很大程度上受網絡的影響。

在高性能的分佈式存儲中,使用傳統的TCP網絡進行各存儲節點之間的網絡互聯很容易形成網絡瓶頸,而在分佈式存儲最容易讓用戶詬病的IO延時方面,網絡部分的開銷是不可忽視的一部分。

隨着網絡帶寬的高速增長,在軟件上的消耗已成爲網絡性能的瓶頸,而通過繞過CPU實現高性能傳輸的RDMA網絡成爲分佈式存儲不錯的選擇。 

RDMA(Remote Direct Memory Access),可以簡單理解爲網卡完全繞過CPU實現兩個服務器之間的內存數據交換。其作爲一種硬件實現的網絡傳輸技術,可以大幅提升網絡傳輸效率,幫助網絡IO密集的業務(比如分佈式存儲、分佈式數據庫等)獲得更低的時延以及更高的吞吐。

最初的RDMA是實現在IB(Infiniband)上,由於其新的硬件技術棧成本比較高,主要用於HPC(高性能計算)等少數場景。而新的技術發展下,能夠實現在以太網上使用RDMA。 

當前RDMA在以太網上的傳輸協議是RoCEv2,RoCEv2是基於無連接協議的UDP協議,相比面向連接的TCP協議,UDP協議更加快速、佔用CPU資源更少,但其不像TCP協議那樣有滑動窗口、確認應答等機制來實現可靠傳輸,一旦出現丟包,依靠上層應用檢查到了再做重傳,會大大降低RDMA的傳輸效率。

所以要想發揮出RDMA真正的性能,突破數據中心大規模分佈式系統的網絡性能瓶頸,勢必要爲RDMA搭建一套不丟包的無損網絡環境,而實現不丟包的關鍵就是解決網絡擁塞。在解決擁塞問題的關鍵在支持ECN等特性的交換機,而這個技術在一般的交換機都普遍支持。

既然RDMA是一個硬件技術方案,而且在分佈式存儲中又能快速地解決網絡高延時等相關問題,是不是直接更換上這個新的硬件技術就能萬事大吉?實際可能並沒有那麼簡單,那麼我們就來簡單聊聊RDMA技術實踐過程中踩過的坑。

RDMA想說愛你卻不容易

  • RDMA的使用需要應用程序的代碼配合(RDMA編程)。

RDMA操作的語義更加貼近硬件實現的語義形態,與傳統TCP/IP的Socket編程有很大的差別,不能直接將現有程序簡單地直接套用RDMA接口,而使用原生RDMA編程庫比Socket編程要複雜很多。

並且在編程方式上RDMA編程是異步的,而原始的Socket編程是同步的。這樣將導致對大多數開發者來說,無論是改造原有應用程序適配RDMA,還是寫一個全新的RDMA原生應用程序,都不容易。

那麼如果完成了RDMA對接,是否就能使我們的程序獲得高性能呢?我們再看看在通信模塊中對接完RDMA的對比性能測試。

  • RDMA在RPC模塊中使用

分佈式存儲中通常使用RPC框架進行節點之間的通信,RPC性能對整體的存儲性能有重要的影響。筆者團隊實現了一個基於C++的RPC框架,可以靈活支持多種數據傳輸協議並支持協程快速處理,適用於有高性能需求的場景。該RPC框架同時支持傳統TCP和RDMA兩種傳輸方式,RDMA方式下注冊了統一管理的RDMA內存,並採用雙邊操作進行數據傳輸,支持事件和輪詢的請求檢測機制。筆者團隊對兩種傳輸方式的性能進行了對比測試,測試結果參見下圖:

圖1 RPC TCP與RDMA性能對比測試

(測試說明:使用同一張10Gb網卡,採用不同的模式進行對比測試)

通過測試我們發現RDMA的方式具有明顯的優勢,尤其在低深度的場景下能獲得更好的性能。我們繼續將RPC對接實際業務進行了測試,在這裏我們對接了一個基於RAFT一致性協議的多副本數據存儲業務,測試結果參見下圖:

圖2 對接實際業務後的性能對比測試

從上面的測試結果看到,在包含有實際業務的測試中,RDMA的表現並沒有原始的RDMA測試表現那麼優異,我們分析了其主要原因是線程切換、數據複製等操作以及IO路徑上其它模塊引入了額外的開銷。

那麼怎樣才能發揮出RDMA的優異性能?在實踐過程中我們也針對分佈式存儲系統Ceph分別使用TCP和RDMA進行了對比測試,測試結果也不是十分滿意,我們發現在Ceph中對於小IO的場景使用不同的傳輸模式都沒有明顯的提升,甚至還有略微的下降,對於大IO的高吞吐情況,還會出現性能的明顯下降,測試結果見下圖:

圖3 Ceph 原生RDMA 1M大塊吞吐測試結果 

在測試結果的基礎上我們分析了Ceph中關於RDMA部分的實現,主要發現存在下面幾個問題:

  1. Ceph中使用雙邊的編程方式,傳輸的過程並沒有繞開CPU,同時Ceph內部使用bufferlist的數據結構,需要多次進行內存拷貝,沒有充分發揮RDMA中零拷貝的特性。

  2. 由於RDMA的異步編程模型,需要進行Polling來檢測數據操作的完成,使用單獨的線程輪詢不但沒有降低CPU,反而有更多的CPU開銷,而如果使用事件機制則會增加延遲降低性能。

RDMA在上述的各個場景中,都沒能充分發揮其優越性能,那麼需要怎樣的編程方式才能發揮其價值呢?筆者團隊又探索了SPDK(Storage performance development kit)的NVMe-oF中的RMDA使用方式。

  • RDMA在NVMe-oF中的使用

NVMe Over Fabrics(NVMe-oF)是使用RDMA或光纖通道(FC)架構等Fabric技術取代PCIe傳輸,從而將把本地高速訪問的優勢暴露給遠端應用的一種傳輸技術。在SPDK中實現了相關的邏輯,下圖是分別通過SPDK的NVMe-oF的target訪問與本地訪問SSD的性能對比測試。

圖4 NVMe-oF 與原始SSD的性能對比測試 

通過上面的數據我們發現,通過RDMA的網絡傳輸的性能和原始的性能非常接近,在單深度的情況下讀延時只增加了11us,寫延時只增加了 18 us。通過多深度能夠跑出與本地SSD相當的性能。上面的測試也進一步論證了正確地使用RDMA的相關編程技術是能夠充分發揮出硬件優越性能的。

我們分析了SPDK中關於RDMA相關的實現,認爲以下因素是RDMA編程實現的關鍵:

  1. 充分利用RDMA的內存註冊機制,整個IO路徑過程中使用內存池中的內存,實現全流程零拷貝。

  2. 對於控制消息(小IO)使用send/recv的雙邊編程方式,對於數據消息(大IO)使用write/read的單邊編程方式。

  3. RDMA的poll與NVMe盤的讀寫處於同一個線程,整個過程沒有線程切換,是全用戶態的IO處理。

 

EDS中的RDMA應用

基於以上對於分佈式存儲中RDMA使用的分析,筆者團隊認爲簡單地生搬硬套發揮不了RDMA與新型存儲設備的性能優勢,從整體框架上進行RDMA適配,將IO路徑上各模塊聯動優化纔是分佈式存儲追求極致性能之路。爲此我們設計驗證了面向RDMA的高性能分佈式存儲框架和實現方案,並在深信服企業級分佈式存儲EDS中落地應用。

EDS針對RDMA網絡和NVMe SSD設計了低延遲高併發的存儲架構,將存儲節點前後端網絡使用RDMA RoCE接入,實現低延遲極速網絡傳輸,並對IO棧上各模塊進行了相應的優化設計。深信服EDS存儲架構採用了run to complete和無鎖化編程模型,並優化了各模塊之間的數據處理,實現系統內全IO棧的內存零拷貝,使整體性能得到了極大的提升。

如圖5所示,前端協議網關(Protocol Gateway,PGW)接收來自用戶的多種協議類型請求(包括NFS,SAMBA,S3,Swift,iSCSI,NVMe-OF等),將這些請求封裝後通過SRPC通信模塊發送到存儲服務端進行處理。存儲服務端解析請求後由存儲引擎進行相應的處理並訪問存儲設備完成數據的寫入和讀取。

前端PGW請求發送和回調、存儲服務端請求處理採用run to complete的方式在同一線程完成,極大地提高單個請求的處理速度,並採用無鎖化編程的方式啓用多個線程分組處理請求,達到請求的高併發。此外設計了統一的數據緩存管理機制,整個請求處理過程從數據經RDMA接收後,經過各模塊處理,再到通過RDMA發送出去,全程不需要對數據進行內存拷貝,進一步減少系統開銷並大幅降低了延遲。

 

圖5 EDS存儲軟件架構示意圖

 SRPC通信模塊設計

(1)通信架構

深信服EDS存儲設計了面向存儲系統消息傳輸的專用網絡通信模塊SRPC,將上層多種類型請求消息封裝,使用RDMA進行快速數據傳輸,可以靈活擴展支持上層NVMe-OF、iSCSI等多種類型協議,並對消息封裝進行了抽象和簡化,減少RPC數據包大小和處理時間。

SRPC的架構如圖6所示,一個服務端server進程綁定一個port監聽連接,server可以設置多個線程作爲多個poll group並行處理請求,從請求接收到處理和回調Reply的整個過程都在同一線程內完成;客戶端client創建channel連接server,可以指定要連接的server線程,client可以設置多線程,並在創建channel時分配其所在的線程。SRPC同時也支持使用TCP協議兼容未配置專用RDMA網卡的場景。

圖6 SRPC通信架構

(2)數據傳輸方式

在使用RDMA操作數據傳輸時,通常有使用雙邊操作傳輸和使用單雙邊操作結合傳輸兩種方式,SRPC選擇了更爲靈活的單雙邊操作結合的方式。

如圖7所示,使用雙邊操作(SEND/RECV)傳輸數據與傳統Socket網絡傳輸類似,發送端使用RDMA SEND發送數據,接收端使用RDMA RECV接收數據。但是在發送端發起RDMA SEND操作之前,接收端需要準備好接收數據的內存區併發起RDMA RECV操作,否則就會發送失敗。因此雙方需要約定一次傳輸最大的數據大小,一般在在創建RDMA連接時協商,接收端以該大小準備接收內存區,發送端以該大小對大請求進行切分。使用雙邊RDMA SEND/RECV的限制在於當請求小於約定大小時存在接收端內存浪費的現象,而請求大於約定大小時需要發送端切分多次傳輸並在接收端重組,並且通常需要應用Buffer到RDMA協議Buffer之間的內存拷貝,增加了開銷和延遲。

 

圖7 RDMA雙邊傳輸方式 

如圖8所示,在單雙邊結合的傳輸方式下,雙邊SEND/RECV多用於控制類消息傳輸,而實際數據則是通過單邊READ/WRITE來完成。在實際場景中每次需要傳輸的數據大小不是固定的,所以發起單邊操作前需要先協商好數據長度和相應的內存區信息。其方式爲先使用雙邊SEND/RECV操作把待傳輸數據的內存地址、大小、rkey等控制信息進行傳輸,然後根據傳輸類型選擇單邊READ或WRITE操作完成實際數據的傳輸,最後使用雙邊SEND/RECV操作發送Reply結果

數據發送到對端在實際場景中每次需要傳輸的數據大小不是固定的,所以發起單邊操作前需要先協商好數據長度和相應的內存區信息。單雙邊結合傳輸的方式具有靈活適應各種大小請求的特點,尤其在傳輸大請求時具有明顯優勢,只需要一次單邊操作即可將數據全部傳輸,同時單雙邊結合的方式也實現了應用Buffer到RDMA協議Buffer之間的數據零拷貝,進一步降低了開銷和延遲。

圖8 RDMA單雙邊結合傳輸方式

SRPC設置了兩種模式進行請求的檢測和處理,分別是性能模式和經濟模式。性能模式下SRPC不間斷輪詢RDMA CQ隊列獲取請求,可以更快地響應請求並進行處理。而經濟模式下SRPC採用RDMA事件觸發與低頻率輪詢相結合的方式來進行請求檢測處理,可以降低對CPU等資源的消耗。

SRPC根據負載採用智能算法自動在兩種模式之間切換,當請求密集時採用性能模式快速處理請求,降低延遲,而當負載較低時則轉入經濟模式,降低CPU等資源使用,降低能耗。

總結

RDMA的編程模式與傳統TCP/IP相比有很大的不同,不管是內存使用機制,還是數據操作邏輯都發生了很大的變化。使用RDMA可以減少在內核協議棧處理和內存拷貝等開銷,從而大幅降低數據在網絡上傳輸的延遲,但實際數據訪問需要經過軟件棧多個模塊的處理,這其中可能存在數據拷貝和同步等開銷,當存儲設備的訪問延遲和網絡傳輸延遲都達到10us級別時,這些軟件棧上的開銷對整體性能的影響變得愈發明顯。

從TCP/IP網絡通信切換到RDMA通信不僅僅是數據收發網絡接口的簡單替換,而是需要進行整體的軟件架構的優化設計,使IO路徑上各模塊契合RDMA的特點整體聯動,才能充分發揮RDMA的優勢,並與NVMe SSD等高性能低延遲設備結合,取得存儲性能的突破。

【作者介紹】

火尉子,華中科技大學博士,研究分佈式存儲、大數據存儲中的數據分佈、性能和可靠性,在國際會議和期刊上發表多篇相關論文,目前主要從事分佈式存儲系統性能提升、網絡通信優化的研發工作,專注於存儲性能優化、RDMA等領域,2018年加入深信服科技。

推薦閱讀

真香,朕在看了!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章