如何调优 TCP Socket 缓冲区
原文:https://access.redhat.com/solutions/369563
环境
- Red Hat Enterprise Linux (RHEL)
问题
- 看到由于套接字缓冲区溢出导致的数据包丢失。
netstat -s报告由于套接字缓冲区过低导致的数据包丢失。
解决方案
如果应用程序未使用 setsockopt 调用来设置其缓冲区大小,则将使用系统默认大小。
- 默认的 TCP 套接字缓冲区大小由以下文件设置:
$ cat /proc/sys/net/ipv4/tcp_rmem
4096 87380 4194304
$ cat /proc/sys/net/ipv4/tcp_wmem
4096 16384 4194304
- TCP 套接字缓冲区是一个灵活的缓冲区,用于在内核级别处理进出数据包。它会根据当前负载动态调整大小。上述文件中的三个数字表示缓冲区的最小值、默认值和最大值。
- 可以通过在
/etc/sysctl.conf文件中添加参数来更改这些值:
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 87380 4194304
对于内存充足且使用 1GB 或 10GB 网卡的机器,如果发生缓冲区裁剪,可以将最大值增加到 16MB。建议在将系统投入生产前,在类似负载下测试这些值。
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
- 这些更改需要通过运行以下命令生效:
# sysctl -p
- 注意不要将缓冲区设置得过大。设置过大可能会对性能产生负面影响。这些缓冲区使用的是系统的物理内存。也就是说,每个 TCP 连接都会占用相应大小的内存。如果缓冲区设置过大,且连接数很多,可能会导致内存不足。此外,每次读写缓冲区时,都会读取整个套接字。这意味着,如果缓冲区大于典型数据包大小,即使实际数据量较小,应用程序也会读取整个缓冲区,从而带来额外开销。
- 有关增加套接字缓冲区大小可能带来的影响,请参阅文章:更改套接字缓冲区大小的影响是什么?
对于通过调用 setsockopt(SO_RCVBUF) 自行设置缓冲区大小的应用程序:
如果上述 sysctl 内存设置未能显著提高吞吐量,建议增加 setsockopt(SO_RCVBUF) 的调用值,或从应用程序代码中移除该调用。移除该调用将允许内核自动调优内存值。
- 还需注意,当使用
setsockopt(SO_RCVBUF)时,应用程序设置的缓冲区大小将受到net.core.rmem_default和net.core.rmem_max的限制。例如,如果应用程序设置了 1MB 的缓冲区,但net.core.rmem_max仅为 256KB,则实际套接字缓冲区将被限制为 256KB。
SO_RCVBUF
设置或获取套接字接收缓冲区的最大字节数。内核在通过 setsockopt(2) 设置时会将该值翻倍(以留出簿记开销),
getsockopt(2) 返回的是翻倍后的值。默认值由 /proc/sys/net/core/rmem_default 文件设置,
最大值由 /proc/sys/net/core/rmem_max 文件设置。该选项的最小值(翻倍后)为 256。
诊断步骤
- 可以通过查看
netstat -s的输出来检查套接字缓冲区是否超载:
$ netstat -s | grep socket
1617 packets pruned from receive queue because of socket buffer overrun
798 TCP sockets finished time wait in fast timer
29 delayed acks further delayed because of locked socket
346941 packets collapsed in receive queue due to low socket buffer
- 如果有数据包被“裁剪”或“折叠”,则可能需要进行调优。
- 请注意,在活动较少的服务器上,可能看不到负载或内存压力的明显变化。
这些 sysctl 更改在连接数达到数千的繁忙服务器上影响更明显。
应相应进行测试。
更改前(非繁忙服务器)
10:00:01 AM kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty
10:50:01 AM 611988 15515156 96.21 1368 8560820 10050932 62.30 8101972 6045188 4604
11:00:01 AM 224920 15902224 98.61 1284 8917416 10182208 63.11 8204204 6331076 4952
更改后(非繁忙服务器)
10:00:01 AM kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty
10:53:39 AM 752268 15374876 95.34 1168 8388744 10207324 63.26 8826552 5067064 768
10:53:40 AM 752832 15374312 95.33 1168 8388744 10206940 63.26 8826848 5067064 768
10:53:41 AM 752052 15375092 95.34 1168 8388744 10207068 63.26 8827452 5067064 880

浙公网安备 33010602011771号