網絡性能優化
傳輸層
傳輸層最重要的是TCP和UDP協定,是以這兒的優化,其實主要就是對這兩種協定的優化
TCP協定的優化
TCP提供了面向連接配接的可靠傳輸服務
要優化TCP首先要掌握TCP協定的基本原理
比如流量控制、慢啟動、擁塞避免、延遲确認以及狀态流圖(如下圖所示)等
分幾類情況詳細說明
-
第一類,在請求數比較大的場景下,可能會看到大量處于TIME_WAIT狀态的連接配接
它們會占用大量記憶體和端口資源
這時,可以優化與TIME_WAIT狀态相關的核心選項,比如采取下面幾種措施
-
增大處于TIME_WAIT狀态的連接配接數量net.ipv4.tcp_max_tw_buckets
并增大連接配接跟蹤表的大小net.netfilter.nf_conntrack_max
-
減小net.ipv4.tcp_fin_timeout和net.netfilter.nf_conntrack_tcp_timeout_time_wait
讓系統盡快釋放它們所占用的資源
-
開啟端口複用net.ipv4.tcp_tw_reuse
這樣被TIME_WAIT狀态占用的端口,還能用到建立的連接配接中
-
增大學地端口的範圍net.ipv4.ip_local_port_range
這樣就可以支援更多連接配接,提高整體的并發能力
-
增加最大檔案描述符的數量
可以使用fs.nr_open ,設定系統的最大檔案描述符數
或在應用程式的systemd配置檔案中,配置LimitNOFILE,設定應用程式的最大檔案描述符數
-
-
第二類,為了緩解SYN FLOOD等
利用TCP協定特點進行攻擊而引發的性能問題,可以考慮優化與SYN狀态相關的核心選項
比如采取下面幾種措施
-
增大TCP半連接配接的最大數量net.ipv4.tcp_max_syn_backlog
或者開啟TCP SYN Cookies net.ipv4.tcp_syncookies
來繞開半連接配接數量限制的問題(注意這兩個選項不可同時使用)
- 減少SYN_RECV狀态的連接配接重傳SYN+ACK包的次數net.ipv4.tcp_synack_retries
-
-
第三類,在長連接配接的場景中,通常使用Keepalive來檢測TCP連接配接的狀态
以便對端連接配接斷開後,可以自動回收
但是系統預設的Keepalive探測間隔和重試次數,一般都無法滿足應用程式的性能要求
是以這時候需要優化與Keepalive相關的核心選項,比如
- 縮短最後一次資料包到Keepalive探測包的間隔時間net.ipv4.tcp_keepalive_time
- 縮短發送Keepalive探測包的間隔時間net.ipv4.tcp_keepalive_intvl
- 減少Keepalive探測失敗後,一直到通知應用程式前的重試次數net.ipv4.tcp_keepalive_probes
優化TCP性能時,還要注意,如果同時使用不同優化方法,可能會産生沖突
比如就像網絡請求延遲案例中,伺服器端開啟Nagle算法,用戶端開啟延遲确認機制,就很容易導緻網絡延遲增大
另外在使用NAT的伺服器上,如果開啟net.ipv4.tcp_tw_recycle ,就很容易導緻各種連接配接失敗
實際上,由于坑太多,這個選項在核心的4.1版本中已經删除了
UDP協定的優化
UDP提供了面向資料報的網絡協定,它不需要網絡連接配接,也不提供可靠性保障
是以UDP 優化,相對于 TCP 來說,要簡單得多
- 跟上篇套接字部分提到的一樣,增大套接字緩沖區大小以及UDP緩沖區範圍
- 跟前面TCP部分提到的一樣,增大學地端口号的範圍
- 根據MTU大小,調整UDP資料包的大小,減少或者避免分片的發生
網絡層
網絡層負責網絡包的封裝、尋址和路由,包括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(Maximum Transmission Unit)的大小
通常MTU的大小應該根據以太網的标準來設定
以太網标準規定一個網絡幀最大為1518B,去掉以太網頭部的18B後,剩餘的1500就是以太網MTU的大小
在使用VXLAN、GRE等疊加網絡技術時,要注意網絡疊加會使原來的網絡包變大,導緻MTU也需要調整
比如,就以VXLAN為例,它在原來封包的基礎上,
增加了14B的以太網頭部、 8B的VXLAN頭部、8B的UDP頭部以及20B的IP頭部
換句話說,每個包比原來增大了50B
是以就需要把交換機、路由器等的MTU,增大到1550
或者把VXLAN封包前 (比如虛拟化環境中的虛拟網卡)的MTU減小為1450
另外現在很多網絡裝置都支援巨幀,如果是這種環境,還可以把MTU調大為9000, 以提高網絡吞吐量
-
第三種,從ICMP的角度出發,為了避免ICMP主機探測、ICMP Flood等各種網絡問題
可以通過核心選項,來限制ICMP的行為
-
禁止ICMP協定,即設定net.ipv4.icmp_echo_ignore_all = 1
這樣,外部主機就無法通過ICMP來探測主機
- 禁止廣播ICMP,即設定net.ipv4.icmp_echo_ignore_broadcasts = 1
-
鍊路層
網絡層的下面是鍊路層,是以最後再來看鍊路層的優化方法
鍊路層負責網絡包在實體網絡中的傳輸,比如MAC尋址、錯誤偵測以及通過網卡傳輸網絡幀等
自然鍊路層的優化,也是圍繞這些基本功能進行的
由于網卡收包後調用的中斷處理程式(特别是軟中斷),需要消耗大量的CPU
是以将這些中斷處理程式排程到不同的CPU上執行,就可以顯著提高網絡吞吐量
這通常可以采 用下面兩種方法
- 可以為網卡硬中斷配置CPU親和性(smp_affinity),或者開啟irqbalance服務
-
可以開啟RPS(Receive Packet Steering)和RFS(Receive Flow Steering)
将應用程式和軟中斷的處理排程到相同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的組包功能
最後對于網絡接口本身,也有很多方法,可以優化網絡的吞吐量
-
可以開啟網絡接口的多隊列功能
這樣每個隊列就可以用不同的中斷号,排程到不同CPU上執行,進而提升網絡的吞吐量
- 可以增大網絡接口的緩沖區大小,以及隊列長度等,提升網絡傳輸的吞吐量 (注意,這可能導緻延遲增大)
- 可以使用Traffic Control工具,為不同網絡流量配置QoS
到這裡就從應用程式、套接字、傳輸層、網絡層,再到鍊路層,分别介紹了相應的網絡性能優化方法
通過這些方法的優化後,網絡性能就可以滿足絕大部分場景了
最後别忘了一種極限場景,C10M問題嗎?
在單機并發1000萬的場景中,對Linux網絡協定棧進行的各種優化政策,基本都沒有太大效果
因為這種情況下,網絡協定棧的冗長流程,其實才是最主要的性能負擔
這時可以用兩種方式來優化
-
第一種,使用 DPDK 技術,跳過核心協定棧,直接由使用者态程序用輪詢的方式,來處理網絡請求
同時,再結合大頁、CPU綁定、記憶體對齊、流水線并發等多種機制,優化網絡包的處理效率
-
第二種,使用核心自帶的XDP技術,在網絡包進入核心協定棧前,就對其進行處理
這樣也可以實作很好的性能
小結
在優化網絡的性能時
可以結合Linux系統的網絡協定棧和網絡收發流程,從應用程 序、套接字、傳輸層、網絡層再到鍊路層等
對每個層次進行逐層優化
實際上分析和定位網絡瓶頸,也是基于這些網絡層進行的
而定位出網絡性能瓶頸後,就可以根據瓶頸所在的協定層,進行優化
- 在應用程式中,主要是優化I/O模型、工作模型以及應用層的網絡協定
- 在套接字層中,主要是優化套接字的緩沖區大小
- 在傳輸層中,主要是優化TCP和UDP協定
- 在網絡層中,主要是優化路由、轉發、分片以及ICMP協定
- 在鍊路層中,主要是優化網絡包的收發、網絡功能解除安裝以及網卡選項
如果這些方法依然不能滿足要求,那就可以考慮,使用DPDK等使用者态方式,繞過核心協定棧
或者,使用XDP,在網絡包進入核心協定棧前進行處理
轉載請注明出處喲~
https://www.cnblogs.com/lichengguo