--- title: RDMA簡介 Zero Copy(林俊諺) tags: Session one --- # TCP - 傳輸控制協定(Transmission Control Protocol) - IP層->傳輸層->網路層 - 不同主機的應用層之間經常需要可靠的、像管道一樣的連接,但是IP層不提供這樣的流機制,而是提供不可靠的包交換。 - TCP為了保證不發生丟包,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。 - 然後接收端實體對已成功收到的包發回一個相應的確認資訊(ACK);如果傳送端實體在合理的往返時延(RTT)內未收到確認 [維基百科](https://zh.wikipedia.org/wiki/传输控制协议) ### 四次請求 - 但凡是基於 TCP 協議通訊的,在通訊之前,客戶端與服務端之間都會在邏輯層面上建立一個雙向通路。注意這裡是邏輯層面上,在物理層面上僅僅只是一條通訊的介質。 - 假設在 A、B 之間修路,我現在在 A 點,我要告訴 B,“我要修一條到你那的路了”,B 同意了,於是路修好了。但這隻能是 A 到 B,你不能逆向行駛,所以還要修一條從 B 到 A 的,這時就是 B 告訴 A,“我也要修一條到你那的路”,A 同意了,這才修好了一個雙向通路。 ![image alt](https://img2018.cnblogs.com/blog/1330952/201811/1330952-20181102165912791-2071142354.png) ### TCP報告頭 ![image alt](https://img2018.cnblogs.com/blog/1330952/201811/1330952-20181102193443246-1501506280.png) 1. 源埠和目的埠,各佔 2 個位元組,分別寫入源埠和目的埠; 2. 序號,佔 4 個位元組,TCP連線中傳送的位元組流中的每個位元組都按順序編號。例如,一段報文的序號欄位值是 301 ,而攜帶的資料共有 100 欄位,顯然下一個報文段(如果還有的話)的資料序號應該從 401 開始; 3. 確認號,佔 4 個位元組,是期望收到對方下一個報文的第一個資料位元組的序號。例如,B 收到了 A 傳送過來的報文,其序列號欄位是 501,而資料長度是 200 位元組,這表明B正確的收到了A傳送的到序號 700 為止的資料。因此,B 期望收到A的下一個資料序號是 701,於是 B 在傳送給 A 的確認報文段中把確認號置為 701 ; 4. 資料偏移,佔 4 位,它指出 TCP 報文的資料距離 TCP 報文段的起始處有多遠; 5. 保留,佔 6 位,保留今後使用,但目前應都位 0; 6. 緊急 URG,當 URG=1,表明緊急指標欄位有效。告訴系統此報文段中有緊急資料; 7. 確認 ACK,僅當 ACK=1 時,確認號欄位才有效。TCP 規定,在連線建立後所有報文的傳輸都必須把 ACK 置 1; 8. 推送 PSH,當兩個應用程序進行互動式通訊時,有時在一端的應用程序希望在鍵入一個命令後立即就能收到對方的響應,這時候就將 PSH=1 ; 9. 復位 RST,當 RST=1 ,表明 TCP 連線中出現嚴重差錯,必須釋放連線,然後再重新建立連線; 10. 同步 SYN,在連線建立時用來同步序號。當 SYN=1,ACK=0,表明是連線請求報文,若同意連線,則響應報文中應該使 SYN=1,ACK=1; 11. 終止 FIN,用來釋放連線。當 FIN=1,表明此報文的傳送方的資料已經發送完畢,並且要求釋放; 12. 視窗,佔 2 位元組,指的是通知接收方,傳送本報文你需要有多大的空間來接受; 13. 檢驗和,佔 2 位元組,校驗首部和資料這兩部分; 14. 緊急指標,佔 2 位元組,指出本報文段中的緊急資料的位元組數; 15. 選項,長度可變,定義一些其他的可選的引數。 ## TCP建立連線的三次握手 最開始的時候客戶端和伺服器都是處於 CLOSED 狀態。主動開啟連線的為客戶端,被動開啟連線的是伺服器。 1. TCP 伺服器程序先建立傳輸控制塊 TCB,時刻準備接受客戶程序的連線請求,此時伺服器就進入了 LISTEN(監聽)狀態; 2. TCP 客戶程序也是先建立傳輸控制塊 TCB,然後向伺服器發出連線請求報文,這是報文首部中的同步位 SYN=1,同時選擇一個初始序列號 seq=x 。TCP規定,SYN 報文段(SYN=1 的報文段)不能攜帶資料,但需要消耗掉一個序號。此時,TCP 客戶端程序進入了 SYN-SENT(同步已傳送狀態)狀態。 3. TCP 伺服器收到請求報文後,如果同意連線,則發出確認報文。確認報文中應該 ACK=1,SYN=1,確認號是ack=x+1,同時也要為自己初始化一個序列號 seq=y,此時,TCP伺服器程序進入了 SYN-RCVD(同步收到)狀態。這個報文也不能攜帶資料,但是同樣要消耗一個序號。 4. TCP 客戶程序收到確認後,還要向伺服器給出確認。確認報文的 ACK=1,ack=y+1,自己的序列號 seq=x+1,此時,TCP 連線建立,客戶端進入 ESTABLISHED(已建立連線)狀態。TCP規定,ACK報文段可以攜帶資料,但是如果不攜帶資料則不消耗序號。 5. 當伺服器收到客戶端的確認後也進入 ESTABLISHED 狀態,此後雙方就可以開始通訊了。 ![image alt](https://img2018.cnblogs.com/blog/1330952/201811/1330952-20181102192509865-1112838369.png) [TCP協議三次握手、四次揮手](https://www.itread01.com/content/1541165359.html) # RDMA DMA ### 什麼是DMA DMA全稱為Direct Memory Access,即直接記憶體訪問。意思是外設對記憶體的讀寫過程可以不用CPU參與而直接進行。我們先來看一下沒有DMA的時候: ![image alt](https://pic1.zhimg.com/80/v2-4d284e5a2d2dbf3bf766c0df86388128_720w.jpg) CPU的最主要工作是計算,而不是進行數據複製,這種工作屬於白白浪費了它的計算能力。為了給CPU“減負”,讓它投入到更有意義的工作中去,後來人們設計了DMA機制: ![image alt](https://pic2.zhimg.com/80/v2-c488b1e291e0db78439fa011cb5db051_720w.jpg) 可以看到總線上又掛了一個DMA控制器,它是專門用來讀寫記憶體的設備。有了它以後,當我們的網卡想要從記憶體中拷貝數據時,除了一些必要的控制命令外,整個數據複製過程都是由DMA控制器完成的。過程跟CPU複製是一樣的,只不過這次是把記憶體中的數據通過總線複製到DMA控制器內部的寄存器中,再複製到I/O設備的存儲空間中。CPU除了關注一下這個過程的開始和結束以外,其他時間可以去做其他事情。 ### 什麼是RDMA RDMA( Remote Direct Memory Access )意為遠程直接地址訪問,通過RDMA,本端節點可以“直接”訪問遠端節點的記憶體。所謂直接,指的是可以像訪問本地記憶體一樣,繞過傳統以太網複雜的TCP/IP網絡協議棧讀寫遠端記憶體,而這個過程對端是不感知的,而且這個讀寫過程的大部分工作是由硬體而不是軟體完成的。 ![image alt](https://pic4.zhimg.com/80/v2-bf1978beaffa7275383827ea935a7a9b_720w.jpg) 傳統網絡中,“節點A給節點B發消息”實際上做的是“把節點A內存中的一段數據,通過網絡鏈路搬移到節點B的內存中”,而這一過程無論是發端還是收段,都需要CPU的指揮和控制,包括網卡的控制,中斷的處理,報文的封裝和解析等等。 上圖中左邊的節點在內存用戶空間中的數據,需要經過CPU拷貝到內核空間的緩衝區中,然後才可以被網卡訪問,這期間數據會經過軟體實現的TCP/IP協議棧,加上各層頭部和校驗碼,比如TCP頭,IP頭等。網卡通過DMA拷貝內核中的數據到網卡內部的緩衝區中,進行處理後通過物理鏈路發送給對端。 對端收到數據後,會進行相反的過程:從網卡內部存儲空間,將數據通過DMA拷貝到內存內核空間的緩衝區中,然後CPU會通過TCP/IP協議棧對其進行解析,將數據取出來拷貝到用戶空間中。 可以看到,即使有了DMA技術,上述過程還是對CPU有較強的依賴。 而使用了RDMA技術之後,這一過程可以簡單的表示成下面的示意圖: ![image alt](https://pic1.zhimg.com/80/v2-98f891e5008a599249f440c637b650ec_720w.jpg) 同樣是把本端內存中的一段數據,複製到對端內存中,在使用了RDMA技術時,兩端的CPU幾乎不用參與數據傳輸過程(只參與控制面)。本端的網卡直接從內存的用戶空間DMA拷貝數據到內部存儲空間,然後硬件進行各層報文的組裝後,通過物理鏈路發送到對端網卡。對端的RDMA網卡收到數據後,剝離各層報文頭和校驗碼,通過DMA將數據直接拷貝到用戶空間記憶體中。 [RDMA概述](https://zhuanlan.zhihu.com/p/138874738) ### 優勢 1. 低延遲性 2. 高傳輸量 3. 低 CPU 使用量 ## TCP和RDMA之比較 ![image alt](https://i.imgur.com/MtM9y6U.png) - RDMA可以簡單理解為利用相關的硬體和網路技術,伺服器的網絡卡之間可以直接讀記憶體,應用程式不需要參與資料傳輸過程,只需要指定記憶體讀寫地址,開啟傳輸並等待傳輸完成即可。 [RDMA](https://hackmd.io/@ACM-Study-Group/HJ6HT219_/https%3A%2F%2Fhackmd.io%2F659pTGA5T7CND0rtj1mqLw%3Fview?fbclid=IwAR2Q3RZr0KrZLbuoe99s2jrm7GC9batbzBpAqrs1Krv93klw4HgSqLgK9WY#RDMA) ## Zero Copy - 指的是不需要在用戶空間和內核空間中來回複製數據。 - 內核Bypass:指的是IO(數據)流程可以繞過內核,即在用戶層就可以把數據準備好並通知硬件準備發送和接收。避免了系統調用和上下文切換的開銷。 ![image alt](https://pic2.zhimg.com/80/v2-a2091c7131fb62a52aa4a8e216bf6345_720w.jpg) - 上圖可以很好的解釋“0拷貝”和“內核Bypass”的含義。上下兩部分分別是基於Socket的和基於RDMA的一次收-發流程,左右分別為兩個節點。可以明顯的看到Socket流程中在軟件中多了一次拷貝動作。而RDMA繞過了內核同時也減少了內存拷貝,數據可以直接在用戶層和硬件間傳遞。 # Memory Copy ### Buffer Copy(BCopy) - 簡單範例程式如下: ``` read(file, tmp_buf, len); write(socket, tmp_buf, len); ``` - 圖示 ![image alt](https://i.imgur.com/qdfc8Gt.png) - 註)上面的圖應該整個階段一起看 step 0:執行read函式 step 1:進入Kernel的syscall read(),檔案資料會經由DMA傳到 Kernel管得Buffer step 1-2:CPU將檔案資料搬到user buffer(tmp_buf)裡。 step 2:執行write,Kernel的syscall write() step 2-3:CPU去user buffer的資料搬到socket buffer裏, step 3:資料進到socket buffer後 step 3-4,4:由DMA(Direct Memory Access(直接記憶體存取))的方式將資料送出去給client。 - 問題分析: - 流程中資料重覆,改掉重複,就能減少記憶體的消耗並增加效能。以硬體的角度來看,直接跳過記憶體的資料暫存最快,把檔案資料都傳到網路去,是最直接最有效率的,但不是所有的硬體都支援。 - 解決方法 - 減少user buffer - 可透過使用mmap來取代read功能 - sendfile函式 ### sendfile函式 - 用sendfile直接取代了read/write兩個函式,並且減少了context switch的次數。 - 範例程式 ``` sendfile(socket, file, len); ``` - 圖示 ![image alt](https://i.imgur.com/ml54DLt.png) (1)sendfile執行後,檔案資料會經由DMA傳給Kernel buffer,再由CPU複製到socket buffer (2)socket buffer的資料再經由DMA傳給client 資料複製次數:3次,2次DMA Copy及1次的CPU Copy - 問題分析: - socket buffer還是重複了。 - 解決方法 - Zero Copy - 硬體提供gather(聚合)功能 - gather(目的): 待發送端不指定存放的資料位址是連續的記憶體空間,可以是分散在記憶體的各個位置。 ### Zero Copy - 這種方式能減少了context switch,也能減少buffer的使用, - 範例程式(程式不變同sendfile) ``` sendfile(socket, file, len); ``` - 圖示: ![image alt](https://i.imgur.com/KWwlzgd.png) sendfile執行後,檔案資料經由DMA傳給Kernel buffer(不會資料至copy到socket buffer),因此socket buffer只需管Kernel buffer的address及資料長度(apend到最後) (2)資料傳給client仍用DMA的方式,但來源則變成kernel buffer。 [Memory Copy](https://hackmd.io/@ACM-Study-Group/HJ6HT219_/https%3A%2F%2Fhackmd.io%2F659pTGA5T7CND0rtj1mqLw%3Fview?fbclid=IwAR2Q3RZr0KrZLbuoe99s2jrm7GC9batbzBpAqrs1Krv93klw4HgSqLgK9WY#Memory-Copy)