【发布时间】:2015-12-07 12:27:53
【问题描述】:
我正在 Linux 上尝试调整 TCP 缓冲区大小,但各种结果让我感到困惑。
测试程序包括服务器和客户端。服务器只是监听一个端口,等待客户端从一个映射文件中发送数据。使用recv 将接收到的数据复制到应用程序缓冲区中,然后丢弃。发送数据时,客户端使用 send 和 mmapped 缓冲区的完整大小作为初始参数。
程序在来自两个不同数据中心的两个节点上运行,它们之间的 ping 响应时间约为 9 毫秒。两个节点都安装了两个千兆以太网控制器。最大吞吐量为 256 MB/s,正确设置发送/接收缓冲区大小应为 256 MB/s * 0.09 s ~ 2415919 字节。
我做了几个实验。
在第一次运行中,我运行了一个服务器实例和一个客户端实例。我没有设置发送缓冲区或接收缓冲区的大小,让内核自动调整它们。本案例的目的是建立其他实验的基线。
此设置下的实际吞吐量约为 117 MB/s。在这种情况下,一对服务器和客户端只使用了一个双向网络控制器。检查ifconfig,我发现大多数数据包都通过eth0 和eth1 之间的单个接口。
然后我尝试了两台服务器和两台客户端,这次吞吐量提高到大约 225 MB/s,更接近理想的最大吞吐量。
这是让我困惑的第一个问题:
-
为什么我需要多个进程来用完带宽? FWIW,下面是
/proc/net/bonding/bond0的一部分:Bonding Mode: IEEE 802.3ad Dynamic link aggregation Transmit Hash Policy: layer3+4 (1) MII Status: up MII Polling Interval (ms): 100 Up Delay (ms): 0 Down Delay (ms): 0
然后我为一对服务器和客户端尝试了几种发送/接收缓冲区大小的组合。下表总结了结果:
| send buf size | recv buf size | throughput | comment |
| (client) | (server) | (MB/s) | |
| 1048576 | - | 51.5 | |
| 2621400 | - | 48.6 | server uses autotuning |
| 524288 | - | 43.3 | |
| 8388608 | - | 36.3 | |
| 2621400 | 2621400 | 33.0 | somewhat the theory value |
| - | 2621400 | 30.4 | client uses autotuning |
| 4194304 | - | 30.3 | |
| 262144 | - | 29.1 | |
| - | 1048576 | 27.9 | |
| 6291456 | 6291456 | 26.5 | |
| 8388608 | 8388608 | 23.9 | |
| 6291456 | - | 22.2 | |
| - | 4194304 | 20.8 | |
| 1048576 | 1048576 | 19.8 | |
| 4194304 | 4194304 | 19.3 | |
| - | 8388608 | 19.3 | |
| - | 6291456 | 13.8 | |
以下是上表提出的其他几个问题:
- 为什么理论值不能产生最佳吞吐量 (117 MB/s)?
- 为什么最好的结果 (51.5 MB/s) 仍然不如内核自动调整的结果 (117 MB/s)?
- 为什么更大的缓冲区会导致吞吐量下降?
提前致谢。
【问题讨论】:
-
您可以通过这个问题在 ServerFault.com 上获得更快的帮助
-
我已经在server fault重新发布了这个问题。
标签: tcp linux-kernel