服务器TCP缓冲区大小设置
Socket的缓存会对tcp性能产生影响,也有无数文章告诉我们应该调大socke缓存。但是究竟调多大?本文就省略测试过程,只讲结果,怎么配置tcp_rmem和tcp_wmem的大小。
查看tcp_rmem和tcp_wmem的文件,文件中包含三个值:
1 | cat /proc/sys/net/ipv4/tcp_rmem |
三个值依次表示:min default max
min:决定 tcp socket buffer 最小长度。
default:决定其默认长度。
max:决定其最大长度。在一个tcp链接中,对应的buffer长度将在min和max之间变化。导致变化的主要因素是当前内存压力。如果使用setsockopt设置了对应buffer长度的话,这个值将被忽略。相当于关闭了tcp buffer的动态调整。
通过估算带宽延迟乘积 (bandwidth delay product, BDP),可以计算要使用的正确接收缓冲区大小
如果发送缓冲区超过BDP,超出部分就没有办法有效地网络传输,同时导致网络过载,容易丢包;
如果发送缓冲区小于BDP,就不能很好地发挥出网络传输效率。
所以,发送缓冲区的大小最好是和BDP靠近。
那么上面的BDP值是怎么计算的呢?
那就是著名的带宽延时积了。即:带宽 X 延时rtt = BDP
下面就用G口,阿里香港做例子计算一下,首先使用ping测量一下rtt时间:
1 | PING 8.210.67.1 (8.210.67.1): 56 data bytes |
可以看到上面阿里的icmp延时不到50ms,那么:
BDP = (带宽G口)128 MBps x (50ms)0.05 s = 6.4 MB
然后下面网址计算一下字节byte数:https://www.elecfans.com/tools/zijiehuansuan.html
6.4MB = 6710886.4byte
上面也就是发送方tcp_wmem的值,接收方tcp_rmem可以配置为发送方的2倍,但是有一个tcp缩放窗口会影响到这个值的大小:net.ipv4.tcp_adv_win_scale
最新内核的这个值默认是1,表示缓存的二分之一用于应用缓存,可用接收窗口占二分之一
net.ipv4.tcp_adv_win_scale
3.10版本前的内核默认值是2,表示缓存的四分之一用于应用缓存,可用接收窗口占四分之三
net.ipv4.tcp_adv_win_scale
这个值设置成 -2,表示缓存的四分之三用于应用缓存,可用接收窗口占四分之一
也就是默认值为1的话,俺们计算的BDP值要 x 4 / 2(乘4除2)
6.4 x 4 / 2 = 12.8MB
但是姥爷建议 tcp_adv_win_scale
值设置为 -2,因为这样俺们设置 tcp_wmem 的容错空间更大,比如还是上面的阿里香港:
6.4 x 4 / 1 = 25.6MB
可以直接写入/etc/sysctl.conf
文件:
1 | net.ipv4.tcp_adv_win_scale = -2 |
依上,美西G口,128 MBps x (160ms)0.16 s x 4 = 81MB