43 | 套路篇:网络性能优化的几个思路(上)
生活随笔
收集整理的這篇文章主要介紹了
43 | 套路篇:网络性能优化的几个思路(上)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
上一節(jié),我們了解了 NAT(網(wǎng)絡(luò)地址轉(zhuǎn)換)的原理,學(xué)會(huì)了如何排查 NAT 帶來的性能問題,最后還總結(jié)了 NAT 性能優(yōu)化的基本思路。我先帶你簡(jiǎn)單回顧一下。 NAT 基于 Linux 內(nèi)核的連接跟蹤機(jī)制,實(shí)現(xiàn)了 IP 地址及端口號(hào)重寫的功能,主要被用來解決公網(wǎng) IP 地址短缺的問題。 在分析 NAT 性能問題時(shí),可以先從內(nèi)核連接跟蹤模塊 conntrack 角度來分析,比如用 systemtap、perf、netstat 等工具,以及 proc 文件系統(tǒng)中的內(nèi)核選項(xiàng),來分析網(wǎng)絡(luò)協(xié)議棧的行為;然后,通過內(nèi)核選項(xiàng)調(diào)優(yōu)、切換到無狀態(tài) NAT、使用 DPDK 等方式,進(jìn)行實(shí)際優(yōu)化。 通過前面的學(xué)習(xí),你應(yīng)該已經(jīng)體會(huì)到,網(wǎng)絡(luò)問題比我們前面學(xué)過的 CPU、內(nèi)存或磁盤 I/O 都要復(fù)雜。無論是應(yīng)用層的各種 I/O 模型,冗長(zhǎng)的網(wǎng)絡(luò)協(xié)議棧和眾多的內(nèi)核選項(xiàng),抑或是各種復(fù)雜的網(wǎng)絡(luò)環(huán)境,都提高了網(wǎng)絡(luò)的復(fù)雜性。 不過,也不要過分擔(dān)心,只要你掌握了 Linux 網(wǎng)絡(luò)的基本原理和常見網(wǎng)絡(luò)協(xié)議的工作流程,再結(jié)合各個(gè)網(wǎng)絡(luò)層的性能指標(biāo)來分析,你會(huì)發(fā)現(xiàn),定位網(wǎng)絡(luò)瓶頸并不難。 找到網(wǎng)絡(luò)性能瓶頸后,下一步要做的就是優(yōu)化了,也就是如何降低網(wǎng)絡(luò)延遲,并提高網(wǎng)絡(luò)的吞吐量。學(xué)完相關(guān)原理和案例后,我就來講講,優(yōu)化網(wǎng)絡(luò)性能問題的思路和一些注意事項(xiàng)。 由于網(wǎng)絡(luò)優(yōu)化思路的內(nèi)容比較多,我們分兩節(jié)來學(xué)習(xí),今天我們先來看上篇。
確定優(yōu)化目標(biāo)
跟 CPU 和 I/O 方面的性能優(yōu)化一樣,優(yōu)化前,我會(huì)先問問自己,網(wǎng)絡(luò)性能優(yōu)化的目標(biāo)是什么?換句話說,我們觀察到的網(wǎng)絡(luò)性能指標(biāo),要達(dá)到多少才合適呢? 實(shí)際上,雖然網(wǎng)絡(luò)性能優(yōu)化的整體目標(biāo),是降低網(wǎng)絡(luò)延遲(如 RTT)和提高吞吐量(如 BPS 和 PPS),但具體到不同應(yīng)用中,每個(gè)指標(biāo)的優(yōu)化標(biāo)準(zhǔn)可能會(huì)不同,優(yōu)先級(jí)順序也大相徑庭。 就拿上一節(jié)提到的 NAT 網(wǎng)關(guān)來說,由于其直接影響整個(gè)數(shù)據(jù)中心的網(wǎng)絡(luò)出入性能,所以 NAT 網(wǎng)關(guān)通常需要達(dá)到或接近線性轉(zhuǎn)發(fā),也就是說, PPS 是最主要的性能目標(biāo)。 再如,對(duì)于數(shù)據(jù)庫(kù)、緩存等系統(tǒng),快速完成網(wǎng)絡(luò)收發(fā),即低延遲,是主要的性能目標(biāo)。 而對(duì)于我們經(jīng)常訪問的 Web 服務(wù)來說,則需要同時(shí)兼顧吞吐量和延遲。 所以,為了更客觀合理地評(píng)估優(yōu)化效果,我們首先應(yīng)該明確優(yōu)化的標(biāo)準(zhǔn),即要對(duì)系統(tǒng)和應(yīng)用程序進(jìn)行基準(zhǔn)測(cè)試,得到網(wǎng)絡(luò)協(xié)議棧各層的基準(zhǔn)性能。 在 怎么評(píng)估系統(tǒng)的網(wǎng)絡(luò)性能 中,我已經(jīng)介紹過,網(wǎng)絡(luò)性能測(cè)試的方法。簡(jiǎn)單回顧一下,Linux 網(wǎng)絡(luò)協(xié)議棧,是我們需要掌握的核心原理。它是基于 TCP/IP 協(xié)議族的分層結(jié)構(gòu),我用一張圖來表示這個(gè)結(jié)構(gòu)。 明白了這一點(diǎn),在進(jìn)行基準(zhǔn)測(cè)試時(shí),我們就可以按照協(xié)議棧的每一層來測(cè)試。由于底層是其上方各層的基礎(chǔ),底層性能也就決定了高層性能。所以我們要清楚,底層性能指標(biāo),其實(shí)就是對(duì)應(yīng)高層的極限性能。我們從下到上來理解這一點(diǎn)。 首先是網(wǎng)絡(luò)接口層和網(wǎng)絡(luò)層,它們主要負(fù)責(zé)網(wǎng)絡(luò)包的封裝、尋址、路由,以及發(fā)送和接收。每秒可處理的網(wǎng)絡(luò)包數(shù) PPS,就是它們最重要的性能指標(biāo)(特別是在小包的情況下)。你可以用內(nèi)核自帶的發(fā)包工具 pktgen ,來測(cè)試 PPS 的性能。 再向上到傳輸層的 TCP 和 UDP,它們主要負(fù)責(zé)網(wǎng)絡(luò)傳輸。對(duì)它們而言,吞吐量(BPS)、連接數(shù)以及延遲,就是最重要的性能指標(biāo)。你可以用 iperf 或 netperf ,來測(cè)試傳輸層的性能。 不過要注意,網(wǎng)絡(luò)包的大小,會(huì)直接影響這些指標(biāo)的值。所以,通常,你需要測(cè)試一系列不同大小網(wǎng)絡(luò)包的性能。 最后,再往上到了應(yīng)用層,最需要關(guān)注的是吞吐量(BPS)、每秒請(qǐng)求數(shù)以及延遲等指標(biāo)。你可以用 wrk、ab 等工具,來測(cè)試應(yīng)用程序的性能。 不過,這里要注意的是,測(cè)試場(chǎng)景要盡量模擬生產(chǎn)環(huán)境,這樣的測(cè)試才更有價(jià)值。比如,你可以到生產(chǎn)環(huán)境中,錄制實(shí)際的請(qǐng)求情況,再到測(cè)試中回放。 總之,根據(jù)這些基準(zhǔn)指標(biāo),再結(jié)合已經(jīng)觀察到的性能瓶頸,我們就可以明確性能優(yōu)化的目標(biāo)。網(wǎng)絡(luò)性能工具
同前面學(xué)習(xí)一樣,我建議從指標(biāo)和工具兩個(gè)不同維度出發(fā),整理記憶網(wǎng)絡(luò)相關(guān)的性能工具。 第一個(gè)維度,從網(wǎng)絡(luò)性能指標(biāo)出發(fā),你更容易把性能工具同系統(tǒng)工作原理關(guān)聯(lián)起來,對(duì)性能問題有宏觀的認(rèn)識(shí)和把握。這樣,當(dāng)你想查看某個(gè)性能指標(biāo)時(shí),就能清楚知道,可以用哪些工具。指標(biāo)工具
這里,我把提供網(wǎng)絡(luò)性能指標(biāo)的工具,做成了一個(gè)表格,方便你梳理關(guān)系和理解記憶。你可以把它保存并打印出來,隨時(shí)查看。當(dāng)然,你也可以把它當(dāng)成一個(gè)“指標(biāo)工具”指南來使用。 再來看第二個(gè)維度,從性能工具出發(fā)。這可以讓你更快上手使用工具,迅速找出想要觀察的性能指標(biāo)。特別是在工具有限的情況下,我們更要充分利用好手頭的每一個(gè)工具,用少量工具也要盡力挖掘出大量信息。工具指標(biāo)
同樣的,我也將這些常用工具,匯總成了一個(gè)表格,方便你區(qū)分和理解。自然,你也可以當(dāng)成一個(gè)“工具指標(biāo)”指南使用,需要時(shí)查表即可。網(wǎng)絡(luò)性能優(yōu)化
總的來說,先要獲得網(wǎng)絡(luò)基準(zhǔn)測(cè)試報(bào)告,然后通過相關(guān)性能工具,定位出網(wǎng)絡(luò)性能瓶頸。再接下來的優(yōu)化工作,就是水到渠成的事情了。 當(dāng)然,還是那句話,要優(yōu)化網(wǎng)絡(luò)性能,肯定離不開 Linux 系統(tǒng)的網(wǎng)絡(luò)協(xié)議棧和網(wǎng)絡(luò)收發(fā)流程的輔助。你可以結(jié)合下面這張圖再回憶一下這部分的知識(shí)。 接下來,我們就可以從應(yīng)用程序、套接字、傳輸層、網(wǎng)絡(luò)層以及鏈路層等幾個(gè)角度,分別來看網(wǎng)絡(luò)性能優(yōu)化的基本思路。應(yīng)用程序
應(yīng)用程序,通常通過套接字接口進(jìn)行網(wǎng)絡(luò)操作。由于網(wǎng)絡(luò)收發(fā)通常比較耗時(shí),所以應(yīng)用程序的優(yōu)化,主要就是對(duì)網(wǎng)絡(luò) I/O 和進(jìn)程自身的工作模型的優(yōu)化。 相關(guān)內(nèi)容,其實(shí)我們?cè)?C10K 和 C1000K 回顧 的文章中已經(jīng)學(xué)過了。這里我們簡(jiǎn)單回顧一下。網(wǎng)絡(luò) I/O 的角度
從網(wǎng)絡(luò) I/O 的角度來說,主要有下面兩種優(yōu)化思路。- 第一種是最常用的 I/O 多路復(fù)用技術(shù) epoll,主要用來取代 select 和 poll。這其實(shí)是解決 C10K 問題的關(guān)鍵,也是目前很多網(wǎng)絡(luò)應(yīng)用默認(rèn)使用的機(jī)制。
- 第二種是使用異步 I/O(Asynchronous I/O,AIO)。AIO 允許應(yīng)用程序同時(shí)發(fā)起很多 I/O 操作,而不用等待這些操作完成。等到 I/O 完成后,系統(tǒng)會(huì)用事件通知的方式,告訴應(yīng)用程序結(jié)果。不過,AIO 的使用比較復(fù)雜,你需要小心處理很多邊緣情況。
進(jìn)程的工作模型
而從進(jìn)程的工作模型來說,也有兩種不同的模型用來優(yōu)化。- 第一種,主進(jìn)程 + 多個(gè) worker 子進(jìn)程。其中,主進(jìn)程負(fù)責(zé)管理網(wǎng)絡(luò)連接,而子進(jìn)程負(fù)責(zé)實(shí)際的業(yè)務(wù)處理。這也是最常用的一種模型。
- 第二種,監(jiān)聽到相同端口的多進(jìn)程模型。在這種模型下,所有進(jìn)程都會(huì)監(jiān)聽相同接口,并且開啟 SO_REUSEPORT 選項(xiàng),由內(nèi)核負(fù)責(zé),把請(qǐng)求負(fù)載均衡到這些監(jiān)聽進(jìn)程中去。
應(yīng)用層的網(wǎng)絡(luò)協(xié)議優(yōu)化
除了網(wǎng)絡(luò) I/O 和進(jìn)程的工作模型外,應(yīng)用層的網(wǎng)絡(luò)協(xié)議優(yōu)化,也是至關(guān)重要的一點(diǎn)。我總結(jié)了常見的幾種優(yōu)化方法。- 使用長(zhǎng)連接取代短連接,可以顯著降低 TCP 建立連接的成本。在每秒請(qǐng)求次數(shù)較多時(shí),這樣做的效果非常明顯。
- 使用內(nèi)存等方式,來緩存不常變化的數(shù)據(jù),可以降低網(wǎng)絡(luò) I/O 次數(shù),同時(shí)加快應(yīng)用程序的響應(yīng)速度。
- 使用 Protocol Buffer 等序列化的方式,壓縮網(wǎng)絡(luò) I/O 的數(shù)據(jù)量,可以提高應(yīng)用程序的吞吐。
- 使用 DNS 緩存、預(yù)取、HTTPDNS 等方式,減少 DNS 解析的延遲,也可以提升網(wǎng)絡(luò) I/O 的整體速度。
套接字
套接字可以屏蔽掉 Linux 內(nèi)核中不同協(xié)議的差異,為應(yīng)用程序提供統(tǒng)一的訪問接口。每個(gè)套接字,都有一個(gè)讀寫緩沖區(qū)。- 讀緩沖區(qū),緩存了遠(yuǎn)端發(fā)過來的數(shù)據(jù)。如果讀緩沖區(qū)已滿,就不能再接收新的數(shù)據(jù)。
- 寫緩沖區(qū),緩存了要發(fā)出去的數(shù)據(jù)。如果寫緩沖區(qū)已滿,應(yīng)用程序的寫操作就會(huì)被阻塞。
- 增大每個(gè)套接字的緩沖區(qū)大小 net.core.optmem_max;
- 增大套接字接收緩沖區(qū)大小 net.core.rmem_max 和發(fā)送緩沖區(qū)大小 net.core.wmem_max;
- 增大 TCP 接收緩沖區(qū)大小 net.ipv4.tcp_rmem 和發(fā)送緩沖區(qū)大小 net.ipv4.tcp_wmem。
- tcp_rmem 和 tcp_wmem 的三個(gè)數(shù)值分別是 min,default,max,系統(tǒng)會(huì)根據(jù)這些設(shè)置,自動(dòng)調(diào)整 TCP 接收 / 發(fā)送緩沖區(qū)的大小。
- udp_mem 的三個(gè)數(shù)值分別是 min,pressure,max,系統(tǒng)會(huì)根據(jù)這些設(shè)置,自動(dòng)調(diào)整 UDP 發(fā)送緩沖區(qū)的大小。
- 為 TCP 連接設(shè)置 TCP_NODELAY 后,就可以禁用 Nagle 算法;
- 為 TCP 連接開啟 TCP_CORK 后,可以讓小包聚合成大包后再發(fā)送(注意會(huì)阻塞小包的發(fā)送);
- 使用 SO_SNDBUF 和 SO_RCVBUF ,可以分別調(diào)整套接字發(fā)送緩沖區(qū)和接收緩沖區(qū)的大小。
小結(jié)
今天,我們一起梳理了常見的 Linux 網(wǎng)絡(luò)性能優(yōu)化方法。 在優(yōu)化網(wǎng)絡(luò)性能時(shí),你可以結(jié)合 Linux 系統(tǒng)的網(wǎng)絡(luò)協(xié)議棧和網(wǎng)絡(luò)收發(fā)流程,然后從應(yīng)用程序、套接字、傳輸層、網(wǎng)絡(luò)層再到鏈路層等,進(jìn)行逐層優(yōu)化。 當(dāng)然,其實(shí)我們分析、定位網(wǎng)絡(luò)瓶頸,也是基于這些進(jìn)行的。定位出性能瓶頸后,就可以根據(jù)瓶頸所在的協(xié)議層進(jìn)行優(yōu)化。比如,今天我們學(xué)了應(yīng)用程序和套接字的優(yōu)化思路:- 在應(yīng)用程序中,主要優(yōu)化 I/O 模型、工作模型以及應(yīng)用層的網(wǎng)絡(luò)協(xié)議;
- 在套接字層中,主要優(yōu)化套接字的緩沖區(qū)大小。
總結(jié)
以上是生活随笔為你收集整理的43 | 套路篇:网络性能优化的几个思路(上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 42 | 案例篇:如何优化 NAT 性能
- 下一篇: 44 | 套路篇:网络性能优化的几个思路