44 | 套路篇:网络性能优化的几个思路(下)
生活随笔
收集整理的這篇文章主要介紹了
44 | 套路篇:网络性能优化的几个思路(下)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在優化網絡的性能時,你可以結合 Linux 系統的網絡協議棧和網絡收發流程,然后從應用程序、套接字、傳輸層、網絡層再到鏈路層等每個層次,進行逐層優化。上一期我們主要學習了應用程序和套接字的優化思路,比如:
- 在應用程序中,主要優化 I/O 模型、工作模型以及應用層的網絡協議;
- 在套接字層中,主要優化套接字的緩沖區大小。
網絡性能優化
傳輸層
傳輸層最重要的是 TCP 和 UDP 協議,所以這兒的優化,其實主要就是對這兩種協議的優化。 我們首先來看 TCP 協議的優化。 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 和 fs.file-max ,分別增大進程和系統的最大文件描述符數;或在應用程序的 systemd 配置文件中,配置 LimitNOFILE ,設置應用程序的最大文件描述符數。
為了緩解 SYN FLOOD 等
第二類,為了緩解 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。
- 跟上篇套接字部分提到的一樣,增大套接字緩沖區大小以及 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 主機探測、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。
- 第一種,使用 DPDK 技術,跳過內核協議棧,直接由用戶態進程用輪詢的方式,來處理網絡請求。同時,再結合大頁、CPU 綁定、內存對齊、流水線并發等多種機制,優化網絡包的處理效率。
- 第二種,使用內核自帶的 XDP 技術,在網絡包進入內核協議棧前,就對其進行處理,這樣也可以實現很好的性能。
小結
這兩節課,我們一起梳理了常見的 Linux 網絡性能優化方法。 在優化網絡的性能時,我們可以結合 Linux 系統的網絡協議棧和網絡收發流程,從應用程序、套接字、傳輸層、網絡層再到鏈路層等,對每個層次進行逐層優化。 實際上,我們分析和定位網絡瓶頸,也是基于這些網絡層進行的。而定位出網絡性能瓶頸后,我們就可以根據瓶頸所在的協議層,進行優化。具體而言:- 在應用程序中,主要是優化 I/O 模型、工作模型以及應用層的網絡協議;
- 在套接字層中,主要是優化套接字的緩沖區大小;
- 在傳輸層中,主要是優化 TCP 和 UDP 協議;
- 在網絡層中,主要是優化路由、轉發、分片以及 ICMP 協議;
- 最后,在鏈路層中,主要是優化網絡包的收發、網絡功能卸載以及網卡選項。
總結
以上是生活随笔為你收集整理的44 | 套路篇:网络性能优化的几个思路(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 43 | 套路篇:网络性能优化的几个思路
- 下一篇: 45 | 答疑(五):网络收发过程中,缓