Linux效能優化實戰學習筆記 第四十四講

2021-10-25 10:19:39 字數 4026 閱讀 4119

上一節,我們學了網路效能優化的幾個思路,我先帶你簡單複習一下。

在優化網路的效能時,你可以結合 linux 系統的網路協議棧和網路收發流程,然後從應用程式、套接字、傳輸層、網路層再到鏈路層等每個層次,進行逐層優化。上一期我們主要

學習了應用程式和套接字的優化思路,比如:

今天,我們順著 tcp/ip 網路模型,繼續向下,看看如何從傳輸層、網路層以及鏈路層中,優化 linux 網路效能。

傳輸層最重要的是 tcp 和 udp 協議,所以這兒的優化,其實主要就是對這兩種協議的優化。

我們首先來看 tcp 協議的優化。

tcp 提供了面向連線的可靠傳輸服務。要優化 tcp,我們首先要掌握 tcp 協議的基本原理,比如流量控制、慢啟動、擁塞避免、延遲確認以及狀態流圖(如下圖所示)等

關於這些原理的細節,我就不再展開講解了。如果你還沒有完全掌握,建議你先學完這些基本原理後再來優化,而不是囫圇吞棗地亂抄亂試。

掌握這些原理後,你就可以在不破壞 tcp 正常工作的基礎上,對它進行優化。下面,我分幾類情況詳細說明。

第一類,在請求數比較大的場景下,你可能會看到大量處於 time_wait 狀態的連線,它們會占用大量記憶體和埠資源。這時,我們可以優化與 time_wait 狀態相關的核心選

項,比如採取下面幾種措施。

第二類,為了緩解 syn flood 等,利用 tcp 協議特點進行攻擊而引發的效能問題,你可以考慮優化與 syn 狀態相關的核心選項,比如採取下面幾種措施。

第三類,在長連線的場景中,通常使用 keepalive 來檢測 tcp 連線的狀態,以便對端連線斷開後,可以自動**。但是,系統預設的 keepalive 探測間隔和重試次數,一般都無

法滿足應用程式的效能要求。所以,這時候你需要優化與 keepalive 相關的核心選項,比

優化 tcp 效能時,你還要注意,如果同時使用不同優化方法,可能會產生衝突。

比如,就像網路請求延遲的案例中我們曾經分析過的,伺服器端開啟 nagle 演算法,而客戶端開啟延遲確認機制,就很容易導致網路延遲增大。

另外,在使用 nat 的伺服器上,如果開啟 net.ipv4.tcp_tw_recycle ,就很容易導致各種連線失敗。實際上,由於坑太多,這個選項在核心的 4.1 版本中已經刪除了。

說完 tcp,我們再來看 udp 的優化。

udp 提供了面向資料報的網路協議,它不需要網路連線,也不提供可靠性保障。所以,udp 優化,相對於 tcp 來說,要簡單得多。這裡我也總結了常見的幾種優化方案。

接下來,我們再來看網路層的優化。

網路層,負責網路包的封裝、定址和路由,包括 ip、icmp 等常見協議。在網路層,最主要的優化,其實就是對路由、 ip 分片以及 icmp 等進行調優。

在需要**的伺服器中,比如用作 nat 閘道器的伺服器或者使用 docker 容器時,開啟ip **,即設定 net.ipv4.ip_forward = 1。

調整資料報的生存週期 ttl,比如設定 net.ipv4.ip_default_ttl = 64。注意,增大該值會降低系統效能。

開啟資料報的反向位址校驗,比如設定 net.ipv4.conf.eth0.rp_filter = 1。這樣可以防止 ip 欺騙,並減少偽造 ip 帶來的 ddos 問題。

通常,mtu 的大小應該根據乙太網的標準來設定。乙太網標準規定,乙個網路幀最大為1518b,那麼去掉乙太網頭部的 18b 後,剩餘的 1500 就是乙太網 mtu 的大小。

在使用 vxlan、gre 等疊加網路技術時,要注意,網路疊加會使原來的網路包變大,導致 mtu 也需要調整。

比如,就以 vxlan 為例,它在原來報文的基礎上,增加了 14b 的乙太網頭部、 8b 的vxlan 頭部、8b 的 udp 頭部以及 20b 的 ip 頭部。換句話說,每個包比原來增大了50b。

所以,我們就需要把交換機、路由器等的 mtu,增大到 1550, 或者把 vxlan 封包前(比如虛擬化環境中的虛擬網絡卡)的 mtu 減小為 1450。

另外,現在很多網路裝置都支援巨幀,如果是這種環境,你還可以把 mtu 調大為 9000,以提高網路吞吐量。

網路層的下面是鏈路層,所以最後,我們再來看鏈路層的優化方法。

鏈路層負責網路包在物理網路中的傳輸,比如 mac 定址、錯誤偵測以及通過網絡卡傳輸網路幀等。自然,鏈路層的優化,也是圍繞這些基本功能進行的。接下來,我們從不同的幾

個方面分別來看。

由於網絡卡收包後呼叫的中斷處理程式(特別是軟中斷),需要消耗大量的 cpu。所以,將這些中斷處理程式排程到不同的 cpu 上執行,就可以顯著提高網路吞吐量。這通常可以採

用下面兩種方法。

比如,你可以為網絡卡硬中斷配置 cpu 親和性(smp_affinity),或者開啟 irqbalance服務。

再如,你可以開啟 rps(receive packet steering)和 rfs(receive flowsteering),將應用程式和軟中斷的處理,排程到相同 cpu 上,這樣就可以增加 cpu

快取命中率,減少網路延遲。

tso(tcp segmentation offload)和 ufo(udp fragmentation offload):在tcp/udp 協議中直接傳送大包;而 tcp 包的分段(按照 mss 分段)和 udp 的分片(按照 mtu 分片)功能,由            網絡卡來完成 。

gso(generic segmentation offload):在網絡卡不支援 tso/ufo 時,將 tcp/udp包的分段,延遲到進入網絡卡前再執行。這樣,不僅可以減少 cpu 的消耗,還可以在發生

丟包時只重傳分段後的包。

lro(large receive offload):在接收 tcp 分段包時,由網絡卡將其組裝合併後,再交給上層網路處理。不過要注意,在需要 ip **的情況下,不能開啟 lro,因為如果

多個包的頭部資訊不一致,lro 合併會導致網路包的校驗錯誤。

gro(generic receive offload):gro 修復了 lro 的缺陷,並且更為通用,同時支援 tcp 和 udp。

rss(receive side scaling):也稱為多佇列接收,它基於硬體的多個接收佇列,來分配網路接收程序,這樣可以讓多個 cpu 來處理接收到的網路包。

vxlan解除安裝:也就是讓網絡卡來完成 vxlan 的組包功能。

到這裡,我就從應用程式、套接字、傳輸層、網路層,再到鏈路層,分別介紹了相應的網路效能優化方法。通過這些方法的優化後,網路效能就可以滿足絕大部分場景了。

最後,別忘了一種極限場景。還記得我們學過的的 c10m 問題嗎?

在單機併發 1000 萬的場景中,對 linux 網路協議棧進行的各種優化策略,基本都沒有太大效果。因為這種情況下,網路協議棧的冗長流程,其實才是最主要的效能負擔。

這時,我們可以用兩種方式來優化。

第一種,使用 dpdk 技術,跳過核心協議棧,直接由使用者態程序用輪詢的方式,來處理網路請求。同時,再結合大頁、cpu 繫結、記憶體對齊、流水線併發等多種機制,優化網路包

的處理效率。

第二種,使用核心自帶的 xdp 技術,在網路包進入核心協議棧前,就對其進行處理,這樣也可以實現很好的效能。

這兩節課,我們一起梳理了常見的 linux 網路效能優化方法。

在優化網路的效能時,我們可以結合 linux 系統的網路協議棧和網路收發流程,從應用程式、套接字、傳輸層、網路層再到鏈路層等,對每個層次進行逐層優化。

實際上,我們分析和定位網路瓶頸,也是基於這些網路層進行的。而定位出網路效能瓶頸後,我們就可以根據瓶頸所在的協議層,進行優化。具體而言:

如果這些方法依然不能滿足你的要求,那就可以考慮,使用 dpdk 等使用者態方式,繞過核心協議棧;或者,使用 xdp,在網路包進入核心協議棧前進行處理。

LinuxIO效能優化實戰學習筆記

以下內容來自極客課程,如對您有幫助,詳細課程請見海報 1.檔案系統 為了方便管理,linux 檔案系統為每個檔案都分配兩個資料結構,索引節點 index node 和目錄項 directory entry 它們主要用來記錄檔案的元資訊和目錄結構。2.slab cache cached sreclai...

學習Linux效能優化實戰 1

程序排程 軟中斷測試工具 最近在極客時間上面發現了倪鵬飛老師的linux效能優化實戰,自己感覺講得很好,有興趣的朋友可以去極客時間上面訂閱。部落格是自己總結學習到的一些命令,記錄下來,以備後面使用。侵刪。uptime 用來看系統過去的 1 5 15 分鐘的平均負載。mpstat p all inte...

Linux效能優化實戰學習筆記 第三講

上下文切換是對任務當前執行狀態的暫存和恢復 當多個程序競爭cpu的時候,cpu為了保證每個程序能公平被排程執行,採取了處理任務時間分片的機制,輪流處理多個程序,由於cpu處理速度非常快,在人類的感官上認為是並行處理,實際是 偽 並行,同一時間只有乙個任務在執行處理。根據 tsuna 的測試報告,每次...