TCP缓冲区大小和以太网绑定

(这个问题原本是堆栈溢出的 ,Andy告诉我可以在这里得到更快的帮助,所以现在重新贴出来。)

我正在尝试在Linux上调整TCP缓冲区大小,但各种结果让我感到困惑。

testing程序包括一个服务器和一个客户端。 服务器只是监听一个端口,等待客户端从一个mmaped文件发送数据。 接收的数据使用recv复制到应用程序缓冲区,然后丢弃。 在发送数据时,客户端使用send完整大小的mmapped缓冲区作为初始参数。

程序在两个不同的数据中心的两个节点上运行,它们之间的ping响应时间约为9毫秒。 两个节点都安装了两个千兆以太网控制器。 最大吞吐量为256 MB / s,发送/接收缓冲区大小的适当设置应该是大约256 MB / s * 0.09 s〜2415919字节。

我做了几个实验。

在第一次运行中,我运行了一个服务器实例和一个客户端实例。 我没有设置发送缓冲区或接收缓冲区的大小,让内核自动调整它们。 这个案例的目的是build立其他实验的基线。

这个设置的实际吞吐量大约是117 MB / s。 在这种情况下,一对服务器和客户端仅使用一个或者两个networking控制器。 使用ifconfig检查,我发现大多数数据包通过eth0eth1之间的单个接口。

然后我尝试了两台服务器和两台客户机,这次吞吐量提高到了225 MB / s左右,接近理想的最大吞吐量。

这是令我困扰的第一个问题:

  1. 为什么我需要多个进程来消耗带宽? 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 / recv缓冲区大小的几种组合。 下表总结了结果:

 | 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 | | 

以上是从上表中提出的其他几个问题:

  1. 为什么理论值不能达到最佳吞吐量(117 MB / s)?
  2. 为什么最好的结果(51.5 MB / s)仍然不如内核自动调整(117 MB / s)的结果?
  3. 为什么较大的缓冲区导致吞吐量较差?

提前致谢。