日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 丢包排查思路简述(tcp+rdma)

發布時間:2024/2/28 linux 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 丢包排查思路简述(tcp+rdma) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

linux 丟包排查思路簡述

    • 概述
      • 網絡包接收流程
      • 網絡包發送流程
    • 丟包排查的思路
      • tcp排查方法
      • rdma排查方法
    • 網絡工具匯總
    • 參考鏈接


概述

我們首先以tcp網絡為例,談談linux系統如何收發網絡包

在進行網絡傳輸時,數據包就會按照協議棧,對上一層發來的數據進行逐層處理;然后封裝上該層的協議頭,再發送給下一層。

  • 傳輸層在應用程序數據前面增加了 TCP 頭;
  • 網絡層在 TCP 數據包前增加了 IP 頭;
  • 而網絡接口層,又在 IP 數據包前后分別增加了幀頭和幀尾。

這些新增的頭部和尾部,都按照特定的協議格式填充,想了解具體格式,你可以查看協議的文檔。

比如,你可以查看這里,了解 TCP 頭的格式。這些新增的頭部和尾部,增加了網絡包的大小,但我們都知道,物理鏈路中并不能傳輸任意大小的數據包。網絡接口配置的最大傳輸單元(MTU),就規定了最大的 IP 包大小。在我們最常用的以太網中,MTU 默認值是 1500(這也是 Linux 的默認值)。一旦網絡包超過 MTU 的大小,就會在網絡層分片,以保證分片后的 IP 包不大于 MTU 值。顯然,MTU 越大,需要的分包也就越少,自然,網絡吞吐能力就越好。

如下圖所示,就是 Linux 通用 IP 網絡棧的示意圖:(圖片參考《性能之巔》圖 10.7 通用 IP 網絡棧繪制)

我們從上到下來看這個網絡棧,可以發現,

  • 最上層的應用程序,需要通過系統調用,來跟套接字接口進行交互;
  • 套接字的下面,就是我們前面提到的傳輸層、網絡層和網絡接口層;
  • 最底層,則是網卡驅動程序以及物理網卡設備。

網卡,作為發送和接收網絡包的基本設備。在系統啟動過程中,網卡通過內核中的網卡驅動程序注冊到系統中。而在網絡收發過程中,內核通過中斷跟網卡進行交互。再結合前面提到的 Linux 網絡棧,可以看出,網絡包的處理非常復雜。所以,網卡硬中斷只處理最核心的網卡數據讀取或發送,而協議棧中的大部分邏輯,都會放到軟中斷中處理。(如果top時發現系統的si比較高,可以通過定位/proc/softirqs中增長較快的軟中斷從而定位問題。)

理解了上述架構,我們就不難理解,為什么tcp的收發過程會牽涉到如下幾個緩沖區:

  • 網卡收發網絡包時,通過 DMA 方式交互的環形緩沖區
  • 網卡中斷處理程序為網絡幀分配的,內核數據結構 sk_buff 緩沖區
  • 應用程序通過套接字接口,與網絡協議棧交互時的套接字緩沖區

網絡包接收流程

  • 當一個網絡幀到達網卡后,網卡會通過 DMA 方式,把這個網絡包放到收包隊列中;然后通過硬中斷,告訴中斷處理程序已經收到了網絡包。
  • 接著,網卡中斷處理程序會為網絡幀分配內核數據結構(sk_buff),并將其拷貝到 sk_buff 緩沖區中;然后再通過軟中斷,通知內核收到了新的網絡幀。
  • 接下來,內核協議棧從緩沖區中取出網絡幀,并通過網絡協議棧,從下到上逐層處理這個網絡幀。比如,
    • 在鏈路層檢查報文的合法性,找出上層協議的類型(比如 IPv4 還是 IPv6),再去掉幀頭、幀尾,然后交給網絡層。
    • 網絡層取出 IP 頭,判斷網絡包下一步的走向,比如是交給上層處理還是轉發。當網絡層確認這個包是要發送到本機后,就會取出上層協議的類型(比如 TCP 還是 UDP),去掉 IP 頭,再交給傳輸層處理。
    • 傳輸層取出 TCP 頭或者 UDP 頭后,根據 < 源 IP、源端口、目的 IP、目的端口 > 四元組作為標識,找出對應的 Socket,并把數據拷貝到 Socket 的接收緩存中。
  • 最后,應用程序就可以使用 Socket 接口,讀取到新接收到的數據了。
  • 網絡包發送流程

    了解網絡包的接收流程后,就很容易理解網絡包的發送流程。網絡包的發送流程就是上圖的右半部分,很容易發現,網絡包的發送方向,正好跟接收方向相反。

  • 首先,應用程序調用 Socket API(比如 sendmsg)發送網絡包。由于這是一個系統調用,所以會陷入到內核態的套接字層中。套接字層會把數據包放到 Socket 發送緩沖區中。
  • 接下來,網絡協議棧從 Socket 發送緩沖區中,取出數據包;再按照 TCP/IP 棧,從上到下逐層處理。比如,傳輸層和網絡層,分別為其增加 TCP 頭和 IP 頭,執行路由查找確認下一跳的 IP,并按照 MTU 大小進行分片。
  • 分片后的網絡包,再送到網絡接口層,進行物理地址尋址,以找到下一跳的 MAC 地址。然后添加幀頭和幀尾,放到發包隊列中。這一切完成后,會有軟中斷通知驅動程序:發包隊列中有新的網絡幀需要發送。
  • 最后,驅動程序通過 DMA ,從發包隊列中讀出網絡幀,并通過物理網卡把它發送出去。
  • 丟包排查的思路

    理解了linux網絡棧的原理,我們就不難去定位丟包問題,

  • 如果是出向丟包,那么肯定是網絡包發送流程出了問題,所以排查第一步是找到什么網絡包出現了丟包重傳。然后再根據網絡包發送流程分析丟包原因
  • 如果是入向丟包,那么肯定是網絡包接收流程出了問題,常見的問題如網絡緩沖器滿了等
  • 關于丟包及其分析設計網絡棧、內核棧的各個層面,筆者在也僅僅稍懂皮毛,歡迎讀者踴躍補充。

    我們可以使用ifconfig可以查看網絡丟包情況

    $ ifconfig net0 net0: flags=6211<UP,BROADCAST,RUNNING,SLAVE,MULTICAST> mtu 1500ether 98:03:9b:8c:63:3a txqueuelen 1000 (Ethernet)RX packets 46725983 bytes 9200932091 (8.5 GiB)RX errors 0 dropped 48193 overruns 0 frame 0TX packets 127710842 bytes 127005910250 (118.2 GiB)TX errors 1 dropped 0 overruns 0 carrier 1 collisions 0
    • RX errors: 表示總的收包的錯誤數量,這包括 too-long-frames 錯誤,Ring Buffer 溢出錯誤,crc 校驗錯誤,幀同步錯誤,fifo overruns 以及 missed pkg 等等。
    • RX dropped: 表示數據包已經進入了 Ring Buffer,但是由于內存不夠等系統原因,導致在拷貝到內存的過程中被丟棄。
    • RX overruns: 表示了 fifo 的 overruns,這是由于 Ring Buffer(aka Driver Queue) 傳輸的 IO 大于 kernel 能夠處理的 IO 導致的,而 Ring Buffer 則是指在發起 IRQ 請求之前的那塊 buffer。很明顯,overruns 的增大意味著數據包沒到 Ring Buffer 就被網卡物理層給丟棄了,而 CPU 無法即使的處理中斷是造成 Ring Buffer 滿的原因之一
    • RX frame: 表示 misaligned 的 frames。

    對于 TX 的來說,出現上述 counter 增大的原因主要包括 aborted transmission, errors due to carrirer, fifo error, heartbeat erros 以及 windown error,而 collisions 則表示由于 CSMA/CD 造成的傳輸中斷。

    dropped與overruns的區別:

    • dropped,表示這個數據包已經進入到網卡的接收緩存fifo隊列,并且開始被系統中斷處理準備進行數據包拷貝(從網卡緩存fifo隊列拷貝到系統內存),但由于此時的系統原因(比如內存不夠等)導致這個數據包被丟掉,即這個數據包被Linux系統丟掉。
    • overruns,表示這個數據包還沒有被進入到網卡的接收緩存fifo隊列就被丟掉,因此此時網卡的fifo是滿的。為什么fifo會是滿的?因為系統繁忙,來不及響應網卡中斷,導致網卡里的數據包沒有及時的拷貝到系統內存,fifo是滿的就導致后面的數據包進不來,即這個數據包被網卡硬件丟掉。所以,個人覺得遇到overruns非0,需要檢測cpu負載與cpu中斷情

    tcp排查方法

    tcp丟包排查方法和工具集比較健全,手段也比較多,一般情況下,我們分析tcp丟包主要分析出向丟包重傳,通過在出向丟包的服務器上抓包,找到出問題的網絡包和對端服務器。

    這里僅舉幾個例子:

  • 通過tcpdump抓包,然后使用wireshark使用過濾器tcp.analysis.retransmission找到重傳的網絡包。
    • wireshark抓重傳包的原理是:由于tcp字段中沒有重傳相關的資源,因此wireshark通過掃描網絡包中SEQ/ACK number, IP ID, source and destination IP address, TCP Port等字段,找到重復包,這些包就是丟包重傳的包。
  • tcpdump作為用戶態進程,勢必要消耗很多系統資源,如果丟包概率很低,丟包出現的時間也很短,使用tcpdump往往會無功而返,Brendan Gregg依托eBPF開發出了輕量級的tcp重傳抓取工具: tcpretrans(包含在bcc工具集中)。這個工具它只抓取所有重傳的包,具體的原理是借助Linux Kernel的ftrace機制在tcp_retransmit_skb這個函數加了一個hook來獲取重傳包的skb地址,然后以這個skb的地址作為hash key去/proc/net/tcp這個文件里面匹配tcp連接信息,然后把發生重傳的這個tcp連接的信息(time,src,sport,dst,dport,state)給打印出來。由于它只抓取該服務器發出的重傳包,所以它的系統開銷是很小的,我們完全可以把它部署到服務器上一直運行著去抓包。
  • rdma排查方法

    目前我遇到的系統(mlx cx4/cx5/cx6),在rdma上主要的指標是入向丟包(out_of_order),其根因有如下幾種情況:

  • 入向丟包服務器的rdma網卡緩沖區擁塞,單憑ecn已經無法限制流量,因此網卡產生出向pfc,伴隨有可能產生入向丟包。有關pfc可以查看筆者之前的文章 淺談RDMA流控設計
  • Roce 2網絡鏈路上dscp配置出錯,RDMA流量跑到了其他的網卡隊里里,而其他的隊列有可能是lossy模式,不能保證無損轉發,因此導致丟包。排查步驟如下:
    • 打開roce v2的tcpdump支持ethtool --set-priv-flags net0 sniffer on(注意,使用完成之后記得關閉ethtool --set-priv-flags net0 sniffer off)
    • 使用tcpdump進行抓包,在wireshark中使用過濾器ip.dsfield.dscp,過濾出dscp錯誤的rdma包。如果存在,說明有dscp入錯隊列的rdma流量。
      • 也可以在抓包的時候使用參數過濾,如:tcpdump -i net2 '(ip and (ip[1] & 0xfc) >> 2 != 46)' -w rdma_retrans.pcap,該語句過濾掉了dscp等于46的網絡包。
    • 抓到包后我們就知道了問題流量的src和dest在哪里,我們可以通過perftest(如ib_send_bw)工具打流確認。
  • 網絡工具匯總

    tcp

    rdma

    RoCE/RDMA Tools

    參考鏈接

  • 在Wireshark的tcptrace圖中看清TCP擁塞控制算法的細節(CUBIC/BBR算法為例)
  • Wireshark tcptrace圖關于丟包重傳細節圖解
  • Linux服務器丟包故障的解決
  • tcp retransmission抓包分析_Wireshark | 1. 網絡抓包分析的利器
  • tcpretrans
  • How-To Dump RDMA Traffic Using the Inbox tcpdump tool (ConnectX-4 and above)
  • Graphing Packet Retransmission Rates with Wireshark tcp.analysis.retransmission
  • Using TCPDUMP to Filter on DSCPtcpdump -i eth0 (ip and (ip[1] & 0xfc) >> 2 == 20) -vvv
  • Understanding mlx5 Linux Counters and Status Parameters
  • Understanding mlx5 ethtool Counters
  • Nak Errors
  • 總結

    以上是生活随笔為你收集整理的linux 丢包排查思路简述(tcp+rdma)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。