Linux網絡編程-tcp緩存設置

最近發現服務的邏輯完成時間很短,可是上游接收到的時間比較長,因此就懷疑是底層數據的序列化/反序列化、讀寫、傳輸有問題,而後懷疑是TCP的讀寫緩存是否是設置過小。如今就記錄下TCP緩存的各配置項以及緩存大小的計算公式。linux

1.有關發送、接收緩存的配置

內核設置的套接字緩存緩存

/proc/sys/net/core/rmem_default,net.core.rmem_default,套接字接收緩存默認值 (bit)bash

/proc/sys/net/core/wmem_default,net.core.wmem_default,套接字發送緩存默認值 (bit)網絡

/proc/sys/net/core/rmem_max,net.core.rmem_max,套接字接收緩存最大值 (bit)併發

/proc/sys/net/core/wmem_max,net.core.wmem_max,發送緩存最大值 (bit)tcp

tcp緩存高併發

/proc/sys/net/ipv4/tcp_rmem:net.ipv4.tcp_rmem,接收緩存設置,依次表明最小值、默認值和最大值(bit)spa

4096    87380    4194304blog

/proc/sys/net/ipv4/tcp_wmem:net.ipv4.tcp_wmem,發送緩存設置,依次表明最小值、默認值和最大值(bit)ip

/proc/sys/net/ipv4/tcp_mem:

94500000    915000000    927000000

對應net.ipv4.tcp_mem,tcp總體緩存設置,對全部tcp內存使用情況的控制,單位是頁,依次表明TCP總體內存的無壓力值、壓力模式開啓閥值、最大使用值,用於控制新緩存的分配是否成功

tcp或者udp的設置會覆蓋內核設置其中只有tcp_mem是用於tcp總體內存的控制,其餘都是針對單個鏈接的。

2.修改配置

sysctl -w net.core.rmem_max=8388608
...
sysctl -w net.ipv4.tcp_mem='8388608 8388608 8388608'

3.估算TCP緩存大小  

以tcp接收緩存爲例(實際上發送窗口=對方的接收窗口),tcp接收緩存有2部分組成:接收窗口及應用緩存,應用緩存用於應用的延時讀及一些調度信息。linux使用net.ipv4.tcp_adv_win_scale(對應文件/proc/sys/net/ipv4/tcp_adv_win_scale)指出應用緩存的比例。

if tcp_adv_win_scale > 0: 應用緩存 = buffer / (2^tcp_adv_win_scale),tcp_adv_win_scale默認值爲2,表示緩存的四分之一用於應用緩存,可用接收窗口占四分之三。

if tcp_adv_win_scale <= 0: 應用緩存 = buffer - buffer/2^(-tcp_adv_win_scale),即接收窗口=buffer/2^(-tcp_adv_win_scale),若是tcp_adv_win_scale=-2,接收窗口占接收緩存的四分之一。

那若是能估算出接收窗口就能算出套接字緩存的大小。如何算接收窗口呢?

BDP(bandwidth-delay product,帶寬時延積) = bandwith(bits/sec) * delay(sec),表明網絡傳輸能力,爲了充分利用網絡,最大接收窗口應該等於BDP。delay = RTT/2。

receive_win = bandwith * RTT / 2
buffer = rec_win/(3/4) (上面知道tcp_adv_win_scale=2時表示接收窗口占buffer的3/4

以咱們的機房爲例,同機房的帶寬爲30Gbit/s,兩臺機器ping可得到RTT大概爲0.1ms,那BDP=(30Gb/1000) * 0.1 / 2 = 1.5Mb,buffer = 1.5Mb * 4 / 3 = 2Mb

 4.TCP緩存的綜合考慮

如第三節咱們真的能設置tcp最大緩存爲2Mb嗎?一般一臺機器會部署多個服務,一個服務內部也每每會創建多個tcp鏈接。但系統內存是有限的,若是有4000個鏈接,滿負荷工做,達到最大窗口。那麼tcp總體消耗內存=4000 * 2Mb = 1GB。

併發鏈接越多,默認套接字緩存越大,則tcp佔用內存越大。當套接字緩存和系統內存必定時,會影響併發鏈接數。對於高併發鏈接場景,系統資源不足,縮小緩存限制;併發鏈接少時,能夠適當放大緩存限制。

linux自身引入了自動調整接收緩存的功能,來使吞吐量最大,(緩存最大值仍是受限於tcp_rmem[2])。配置項以下。

net.ipv4.tcp_moderate_rcvbuf = 1 (/proc/sys/net/ipv4/tcp_moderate_rcvbuf)
相關文章
相關標籤/搜索