DBA必備技能之網路丟包分析總結
來源:PostgreSQL學徒
前言
最近一直在惡補網路有關的知識,主要在學習如何分析網路丟包以及網路效能最佳化,我會分成兩篇來總結,第一篇先總結下網路丟包,對於DBA來說,網路和資料庫息息相關,我碰到因為丟包導致莫名其妙的流複製衝突導致備庫卡住,也遇到過丟包導致PostgreSQL效能驟降的案例,因此作為全乾工程師,掌握基本的網路分析技能是十分重要的!
協議
首先是耳熟能詳的協議了,也是瞭解入門網路的基礎之一。就如同人與人之間相互交流是需要遵循一定的規則一樣,計算機之間的相互通訊也同樣需要遵守一定的規則,這些規則就是網路協議。
以OSI標準模型為例,分為物理層、資料鏈路層、網路層、傳輸層、會話層、表示層和應用層。
每一層都有自己的功能,各司其職,就像建築物一樣,每一層都靠下一層支援,每一層傳輸單位都有不同的名詞,資料鏈路層的傳輸單位是幀,IP 層的傳輸單位是包,TCP 層的傳輸單位是段,HTTP 的傳輸單位則是訊息或報文,這些名詞可以統稱為資料包。參照下圖??
物理層確保原始的資料可在各種物理媒體上傳輸,可以用光纜、電纜、雙絞線、無線電波等方式 資料鏈路層在不可靠的物理介質上提供可靠的傳輸,採用差錯檢測、差錯控制和流量控制等方法,向網路層提供高質量的資料傳輸服務,對於網路層,由於鏈路層的存在,而不需要關心物理層具體採用了那種傳輸介質和通訊裝置,主要協議是乙太網 (Ethernet)。乙太網規定,一組電訊號構成一個資料包,叫做"幀" (Frame) ,資料幀不是無限大的,資料幀長度受MTU限制,我們可以透過ifconfig看到 網路層,最熟悉的就是IP協議了,將資料傳輸到目的地址,主要負責定址和路由選擇,與IP協議配套使用實現其功能的最常用的就是ICMP了,常用在ping:網路故障的排查和traceroute:探測IP資料包在網路中走過的路徑,IP 層的傳輸單位是包 (packet) 傳輸層,有兩個傳輸協議,分別是 TCP 和 UDP,大部分應用使用的正是 TCP 傳輸層協議,TCP 相比 UDP 多了很多特性,比如流量控制、超時重傳、擁塞控制等,這些都是為了保證資料包能可靠地傳輸給對方。UDP 就相對很簡單,簡單到只負責傳送資料包,不保證資料包是否能抵達對方,但它實時性相對更好,傳輸效率也高。當傳輸層的資料包大小超過 MSS(TCP 最大報文段長度),就要進行分塊,每個分塊稱為一個"段" (TCP segment) 會話層,主要是管理和協調不同主機上各種程式之間的通訊(對話),即負責建立、管理和終止應用程式之間的會話。網路檔案系統(NFS)和伺服器訊息塊(SMB)是會話層的常用協議。 表示層,負責資料格式的互相轉換,如編碼、資料格式轉換和加密解密等。保證一個系統應用層發出的資訊可被另一系統的應用層讀出。 應用層,OSI 標準模型的最頂層,是直接為應用程式提供服務的。包括檔案傳輸、電子郵件遠端登入和遠端介面呼叫等協議。
網路收發流程
可以看到,在資料包的傳送過程中,各層依次對資料包新增了首部資訊,每個首部都包含傳送端和接收端地址以及上一層的協議型別。乙太網會使用 MAC 地址、IP 會使用 IP 地址、TCP/UDP 則會用埠號作為識別兩端主機的地址。
從宏觀角度看收包過程:
網路報文透過物理網線傳送到網路卡 網路驅動程式會把網路中的報文讀出來放到 ring buffer 中,這個過程使用 DMA 將資料包對映到記憶體 核心從 ring buffer 中讀取報文進行處理,執行 IP 層和 TCP/UDP 層的邏輯,最後把報文放到應用程式的 socket buffer 中 應用程式從 socket buffer 中讀取報文進行處理
因此丟包會涉及到⽹卡、驅動、核心協議棧三⼤類,每一層都有可能會丟包:
在兩臺 VM 連線之間,可能會發生傳輸失敗的錯誤,比如網路擁塞、線路錯誤等; 在網路卡收包後,環形緩衝區可能會因為溢位而丟包; 在 IP 層,可能會因為路由失敗、組包大小超過 MTU 等而丟包; 在傳輸層,可能會因為埠未監聽、資源佔用超過核心限制等而丟包; 在套接字層,可能會因為套接字緩衝區溢位而丟包; 在應用層,可能會因為應用程式異常而丟包;
此處推薦閱讀下飛哥的圖解 Linux 網路包傳送過程
“在Linux核心實現中,鏈路層協議靠網路卡驅動來實現,核心協議棧來實現網路層和傳輸層。核心對更上層的應用層提供socket介面來供使用者程式訪問。
硬體網路卡層
物理介質上的資料幀到達後首先由NIC讀取,寫入裝置內部緩衝區Ring Buffer中,再由中斷處理程式觸發Softirq從中消費,Ring Buffer的大小因網路卡裝置而異。當網路資料包到達(生產)的速率快於核心處理(消費)的速率時,Ring Buffer很快會被填滿,新來的資料包將被丟棄;
我們可以透過ethtool、netstat或者cat /proc/net/dev檢視因Ring Buffer滿而丟棄的包統計
ring buffer的大小我們可以透過ethtool進行檢視以及修改
-g
:Display the rx/tx ring parameter information of the specified ethernet card。-G
:change the rx/tx ring setting of the specified ethernet card。
思維導圖 (From Alex——網路排障全景指南v1.0精簡版)
驅動層
我們可以使用ifconfig檢視
RX-ERROR:表示總的收包的錯誤數量,這包括 too-long-frames 錯誤,Ring Buffer 溢位錯誤,crc 校驗錯誤,幀同步錯誤,fifo overruns 以及 missed pkg 等等。 RX-DROP:表示資料包已經進入了 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 相關的類似,指傳送時對應的各個指標。
另外一個常見原因是單核CPU軟中斷佔有高,導致應用沒有機會收發或者收包比較慢,我們可以使用 ethtool -x檢視,這些指標顯示了介面如何處理入站網路流量,透過雜湊函式和轉向表來分配到不同的接收環,從而實現在多處理器系統中的負載均衡。
這裡要提一下網路卡多佇列 RSS(Receive Side Scaling)是網路卡的硬體特性(需要硬體支援),實現了多佇列,多佇列是RX/TX多個通路,分別負責各種的中斷,可以將不同的流分發到不同的CPU上;
我們可以使用ethtool -l檢視支援的佇列數,以及ethtool -L eth0 combined 4修改佇列數
配置了之後,我們可以使用cat /proc/interrupts檢視當前是否已經開啟了網路卡多佇列,透過檢視網路卡的中斷集中分佈在哪些CPU上,如果分佈在多個CPU上,則當前已經開啟了網路卡多佇列。以及透過綁核的方式將中斷繫結到具體的CPU上
echo "1" > /proc/irq/31/smp_affinity
echo "1" > /proc/irq/32/smp_affinity
echo "2" > /proc/irq/33/smp_affinity
echo "2" > /proc/irq/34/smp_affinity
echo "4" > /proc/irq/35/smp_affinity
echo "4" > /proc/irq/36/smp_affinity
echo "8" > /proc/irq/37/smp_affinity
echo "8" > /proc/irq/38/smp_affinity
當然也可以透過irqbalance,irqbalance避免所有的IRQ請求都由單一的CPU負擔,從而將硬體中斷分佈到多處理器系統的各個處理器以便能夠提高效能,安裝方式為:yum -y install irqbalance
;
思維導圖 (From Alex——網路排障全景指南v1.0精簡版)
網路層
網路層我們可以使用 netstat -s 進行過濾
以下是來自GPT4的回答:
total packets received: The total number of packets received by the interface. 介面接收到的資料包總數。 forwarded: The number of packets that were forwarded to another interface. 被轉發到另一個介面的資料包數量。 incoming packets discarded: The number of incoming packets that were chosen not to be processed (discarded). 選擇不處理(丟棄)的傳入資料包數量。 incoming packets delivered: The number of packets that were successfully delivered to the local higher layers. 成功交付給本地高層的資料包數量。 requests sent out: The number of requests sent from the local host. 從本地主機傳送出去的請求數量。 outgoing packets dropped: The number of outgoing packets that were dropped and not sent. 被丟棄未傳送的傳出資料包數量。 dropped because of missing route: The number of packets dropped because there was no route found to their destination. 因為沒有找到目的地的路由而被丟棄的資料包數量。 reassemblies required: The number of packets that needed to be reassembled from fragments. 需要從碎片中重組的資料包數量。 packets reassembled ok: The number of packets that were successfully reassembled. 成功重組的資料包數量。 fragments received ok: The number of fragment packets that were successfully received. 成功接收的碎片包數量。
ICMP也是類似,此處就不再演示了。
另外一類可能的原因就是防火牆了, iptables -nvL |grep DROP ;
思維導圖 (From Alex——網路排障全景指南v1.0精簡版)
傳輸層
傳輸層協議包括TCP和UDP,也可以使用netstat檢視
可以看到 retransmitted 就是 TCP重傳次數,bad 就是錯誤報文數,這個結果告訴我們TCP 協議有多次重傳。至於下方的TcpExt,各個指標就不細展開了,可以詢問GPT。
另外需要提及的是TIME_WAIT過多丟包,大量TIME_WAIT出現,並且需要解決的場景,在高併發短連線的TCP伺服器上,當伺服器處理完請求後立刻按照主動正常關閉連線。這個場景下,會出現大量socket處於TIMEWAIT狀態。如果客戶端的併發量持續很高,此時部分客戶端就會顯示連線不上,新建立 TCP 連線會出錯,address already in use : connect 異常
我們可以調整允許 time_wait 狀態的 socket 被重用,tw_reuse,tw_recycle ,以及記憶體足夠的話調整tcp_max_tw_buckets大小。
思維導圖 (From Alex——網路排障全景指南v1.0精簡版)
套接字
[root@localhost ~]# netstat -s|grep "packet receive errors"
8878816 packet receive errors
可以看到有大量的socket快取區接收丟包,我們可以調整socket緩衝區大小
# Default Socket Receive Buffer
net.core.rmem_default = 31457280
# Maximum Socket Receive Buffer
net.core.rmem_max = 67108864
類似的還有應用傳送太快導致丟包,以類似方式最佳化。
[root@localhost ~]# netstat -s|grep "send buffer errors
# Default Socket Send Buffer
net.core.wmem_default = 31457280
# Maximum Socket Send Buffer
net.core.wmem_max = 33554432
思維導圖 (From Alex——網路排障全景指南v1.0精簡版)
實用工具
除了前文提到的ethtool、netstat之類的命令,還推薦一個命令——sar,
-n DEV:網路介面統計資訊。 -n EDEV:網路介面錯誤。 -n IP:IP 資料包統計資訊。 -n EIP:IP 錯誤統計資訊。 -n TCP:TCP 統計資訊。 -n ETCP:TCP 錯誤統計資訊。 -n SOCK:套接字使用。
看個例子,比如 sar -n DEV 1 | awk 'NR == 3 || $3 == "eth0"'只分析eth0
rxpck/s / txpck/s:網路卡接收/傳送的資料包,單位是:資料包/s。 rxkB/s / txkB/s:網路卡接收/傳送的千位元組,單位是:千位元組/s。 rxcmp/s / txcmp/s:網路卡每秒接受/傳送的壓縮資料包,單位是:資料包/s。 rxmcst/s:每秒接收的多播資料包,單位是:資料包/s。 %ifutil:網路介面的利用率。
rxerr/s / txerr/s:每秒鐘接收/傳送的壞資料包 coll/s:每秒衝突數 rxdrop/s:因為緩衝充滿,每秒鐘丟棄的已接收資料包數 txdrop/s:因為緩衝充滿,每秒鐘丟棄的已傳送資料包數 txcarr/s:傳送資料包時,每秒載波錯誤數 rxfram/s:每秒接收資料包的幀對齊錯誤數 rxfifo/s / txfifo/s:接收/傳送的資料包每秒 FIFO 過速的錯誤數
totsck 當前被使用的socket總數 tcpsck 當前正在被使用的TCP的socket總數 udpsck 當前正在被使用的UDP的socket總數 rawsck 當前正在被使用於RAW的skcket總數 ip-frag 當前的IP分片的數目 tcp-tw TCP套接字中處於TIME-WAIT狀態的連線數量
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027826/viewspace-2996097/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 網路丟包分析
- Linux 網路分析必備技能:tcpdump 實戰詳解LinuxTCP
- 影像處理演算法工程師必備技能總結演算法工程師
- 資料分析師必備技能都有哪些?
- 開發網站的必備技能網站
- Hacker必備技能
- Android技能樹 — 網路小結(1)之網路體系結構Android
- 網路安全工作必備技能,系統安全有網路安全工程師來守護工程師
- 優秀開發者必備技能包:Python偵錯程式Python
- Android技能樹 — 網路小結(2)之TCP/UDPAndroidTCPUDP
- Android技能樹 — 網路小結(3)之HTTP/HTTPSAndroidHTTP
- 前端切圖必備技能前端
- 【科普篇】入行必備的網路安全術語彙總!
- 產品必備技能(三):網際網路資料分析師、產品經理和運營常用資料網站合集網站
- Android技能樹 — 網路小結(4)之socket/websocket/webserviceAndroidWeb
- 網路分流器-網路丟包以及修復方法
- linux網路工程師需要掌握哪些技能?linux網路工程師技能分析Linux工程師
- Java1.7的HashMap原始碼分析-面試必備技能JavaHashMap原始碼面試
- web前端工程師必備技能Web前端工程師
- 網路基礎都有哪些必備技能?Linux面試題Linux面試題
- 【初學者必備】網路安全學習經驗彙總!
- RMAN備份相關知識與技能總結
- grafana 網路丟包率檢測設定Grafana
- 程式設計師必備畫圖技能之——時序圖程式設計師時序圖
- 網路丟包,網路延遲,這款神器幫你搞定所有
- Java程式設計師必備技能Java程式設計師
- C#必備技能—專案打包C#
- 架構必備技能第一談架構
- 2017.3.14java方向必備技能掌握Java
- Fiddler(8)設定網路丟包和延遲
- Python入門必備知識點總結Python
- 網路問題排查必備利器:Pingmesh
- 大資料系統管理必備技能大資料
- Android技能樹 — 網路小結(7)之 Retrofit原始碼詳細解析Android原始碼
- 運維必知 | 從底層到應用,入門大資料必備技能彙總!運維大資料
- 網路流總結
- java面試題總結(開發者必備)Java面試題
- golang 後端技術開發必備總結Golang後端