如果我們的預期是將網絡延時從10ms 降低到1ms,那么應該先分析這些時延的具體構成,很有可能瓶頸并不是網絡傳輸;如果目標是將網絡延時降低到微秒級或者百微秒級,那么我們才可能使用到高性能網絡,例如RDMA技術。
1. TCP/IP 協議棧的局限
數據中心內部服務器的接入帶正在由萬兆(10G)接入升級為25G,在某些用于機器學習的服務器上甚至使用了100G的接入帶寬。量變引起質變,增大的接入帶寬讓傳統的TCP/IP協議棧遇到了嚴重的性能挑戰。
在當前的操作系統中,使用TCP傳輸數據,需要大量的CPU參與,包括報文的封裝解析和流控處理等。一個TCP報文均由一個CPU核處理,單個TCP流的最大吞吐受制于CPU單核的處理能力。無奈的是,CPU單核計算能力幾乎不能再提升了,這導致采用TCP/IP協議棧的數據傳輸一定會遇到吞吐量瓶頸。如果想充分地利用100G的帶寬,就必須使用多個流的并行傳輸。這一方面增加了應用程序的復雜度,另一方面也意味著不得不將更多昂貴的計算資源投入到網絡傳輸的領域中去。
除了帶寬以外,時延同樣是使用傳統TCP/IP協議棧的一個主要痛點。一個應用程序要發送數據,必須先通過socket API,數據從用戶態進入到內核態,經過內核的報文處理后,再交給網絡協議棧發送出去。類似地,在接收端,內核先收到報文,進行處理后提取出數據,等待用戶態的處理。這中間需要經過操作系統在內核態/用戶態轉化,要經過CPU的報文處理,也還要依賴操作系統的中斷。因此,在小數據量的傳輸時延中,主要延時并非是在物理網絡上的傳輸時延,而是在發送/接收軟件協議棧中的處理時延。
2. 高性能IB網絡
在高性能計算集群中,網絡協議一般不是Ethernet+TCP/IP,而是Infiniband(IB)協議,是從物理層到傳輸層的一整套協議棧。Infiniband的物理接口與以太網接口是完全不同的,是一套完全不同于一般數據中心中以太網架構的網絡。
Infiniband是完全基于集中控制的一種網絡設計,簡化了交換設備的復雜度,有助于降低轉發時延,但這也就導致了IB網絡的擴展性不如以太網。作為超級計算機思想的自然延伸,Infiniband對上層表現為一條計算機內的總線,并不采用Best Effort的轉發策略,而采用了避免丟包的lossless設計,并且上層編程接口開放了直接針對遠程內存的Read/Write。
Infiniband的傳輸層協議是RDMA,即Remote Direct Memory Access,利用了底層網絡lossless的特性,并向上層應用程序提供一種稱為verbs API的編程接口。RDMA從設計之初就是讓硬件網卡ASIC來執行網絡傳輸相關操作的。
第一個Infiniband的標準成形于2000年,自產生以來在HPC領域得到了大量的使用。直到2010年,首個RDMA over Converged Ethernet(RoCE)標準形成,宣告IB網絡的傳輸層協議RDMA可以以覆蓋網絡的形式運行于以太網之上,RoCE的性能相比Infiniband還是要差一些的。自此,IB網絡和以太網正式發生交疊,RDMA技術開始進入一般數據中心,為即將到來的AI計算和云計算的爆發式增長提供了關鍵支持。
3. RDMA的特性
當我們使用RDMA的時候,應用程序的實際數據發送根本不用經過內核處理,也不用拷貝,而是由RDMA網卡直接從用戶態內存中DMA到網卡上,然后在網卡硬件上進行封裝等處理,而接收端也是從網卡上解封裝處理后,直接把數據DMA給用戶態內存。這就是RDMA技術中kernel bypass和zero copy兩個特性的真正涵義。
正是因為kernel bypass和zero copy,RDMA獲得了三個關鍵的衍生特性:低時延、高帶寬和低CPU消耗。這三個衍生特性往往作為RDMA相對于TCP/IP協議棧的主要優勢被提出。需要特別注意的是,kernel bypass和zero copy都需要網卡的硬件支持,這意味著若想用RDMA,就必須要擁有支持RDMA技術的網卡。
上圖中RDMA的左邊經過libibverbs的部分一般稱為Command Channel,是應用程序調用verbs API時的命令通道,并不是真正的數據通道。
3.1 RDMA的verbs API
應用程序使用RDMA用的是verbs API,而不是socket API。RDMA有三種隊列:Send Queue(SQ)、Recv Queue(RQ)和Completion Queue(CQ)。SQ和RQ往往成對出現,合起來稱為Queue Pair。SQ是發送請求隊列,RQ就是接收請求隊列,CQ就是發送請求和接收請求完成情況的隊列。
當一個應用程序需要發送數據的時候,會向SQ里提交一個發送請求(API:ibvpostsend),這個請求并不包含數據本身,只包含指向數據的指針以及數據的長度,提交操作是通過API實現的。這個請求會傳遞到網卡,由網卡自己按照地址和長度把要發送的數據取出,然后發送到網絡。發送完成后,會在CQ中生成一個發送完成的說明。在接收端,應用程序必須事先提交一個接收請求到RQ(API:ibvpostrecv),這個接收請求里包含了接收數據要存放的內存指針以及可以接收的最大數據長度。當數據到來的時候,網卡會將數據放在RQ隊列頭中的接收請求所指明的內存位置,然后在CQ中生成一個接收完成的說明。verbs API的發送與接收都是異步非阻塞的調用,應用程序需要檢查CQ中來判斷一個請求的完成情況,QP可以視為類似socket。
其實在RDMA中,除了Send/Recv以外,還有RDMA Write/Read的特別請求,可以直接實現對遠端應用程序虛擬內存的訪問。RDMA Write/Read請求也是向發起端SQ提交的),但與Send/Recv不同的是,另一端并不需要事先向RQ提交接收請求。這種單邊的RDMA傳輸方式會比Send/Recv有更好的性能,不過必須事先知道數據在對端的確切地址。
3.2 RDMA 的無丟包實現
丟包本身就是網絡傳輸的性能殺手,而且為了從丟包中快速恢復,需要引入復雜的、難以用硬件實現的處理邏輯。以太網可以利用pause機制變成無丟包的,無丟包機制的實現對RDMA是至關重要的,在RoCE中啟用pause機制的時候,為了盡可能限制pause的副作用,可以在網絡中分出不同的優先級隊列,僅僅在特定的優先級隊列上開啟pause,這就是以太網的優先級流控(PFC)機制,已經作為DCB標準的一部分。現在多數的數據中心交換機都已經支持PFC。在PFC配置生效的情況下,RDMA流量跑在開啟了pause的優先級下,而讓TCP的流量跑在沒有開啟pause的優先級下來盡可能限制pause機制所帶來的副作用。
RDMA可以在特殊設計下放棄PFC配置,但這樣的設備還沒有真正誕生,依然要假定RDMA需要無丟包的底層網絡,RDMA的正常使用高度依賴于網絡內交換設備以及網卡的正確配置。
3.3 RDMA的相關技術
RDMAcm,全稱為RDMA communication manager,是對verbs API的一個封裝調用庫。RDMAcm的API近似于socket API,如rdmaconnect,rdmalisten,rdma_accept等,只是作為部分verbs API的一個簡化使用方案而已。rsocket是包含在librdmacm中的一個工具,可以把RDMA使用封裝為socket接口,替代系統默認的socket,從而使得應用程序在不修改代碼的情況下使用RDMA。
DPDK源自Intel的網卡kernel bypass技術,在數據中心中得到了廣泛的應用。DPDK和RDMA沒有直接關系,但都可以kernel bypass,不免有時會拿來對比。DPDK相比RDMA,主要有兩個不同:一是DPDK必須輪詢,會消耗CPU資源;二是DPDK仍需要由用戶態做報文處理,這部分的時延和開銷并沒有降低。然而,DPDK有一個優勢,即其不需要通信對端也做同樣的支持,RDMA和DPDK各有屬于自己的應用場景。
3.4 RDMA 的典型應用場景
RDMA當前最主要的應用場景有兩類:一是高性能計算,包括分布式機器學習訓練(尤其是使用GPU的時候);二是計算存儲分離。前者主要關注高帶寬,例如tensorflow、paddlepaddle等。后者主要關注低時延,代表性案例有nvmf、smb direct等。另外,RDMA在大數據處理(如spark)和虛擬化(如虛機遷移)等場景中也有應用,更多的使用場景仍在探索之中。
4 小結
對于高性能網絡而言,通過kernel bypass和zero copy,RDMA實現了網絡傳輸的低時延、高帶寬與低CPU消耗。一般地,應用程序需要通過特殊的API來使用RDMA,而RDMA則需要底層網絡具備無丟包配置,其主要應用場景包括了高性能計算以及計算存儲分離。