gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 02:34:28 27 4
gpt4 key购买 nike

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

测试程序包括服务器和客户端。服务器简单地监听一个端口,等待客户端从映射文件发送数据。使用 recv 将接收到的数据复制到应用程序缓冲区中,然后将其丢弃。发送数据时,客户端使用 send 并将映射缓冲区的完整大小作为初始参数。

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

我做了几个实验。

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

此设置中的实际吞吐量约为 117 MB/s。在这种情况下,一对服务器和客户端仅使用一个 eithernet Controller 。检查 ifconfig,我发现大多数数据包都通过 eth0eth1 之间的单个接口(interface)。

然后我尝试了两个服务器和两个客户端,这次吞吐量上升到大约 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 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. 为什么缓冲区越大,吞吐量越低?

提前致谢。

最佳答案

我对几个问题的分析。

需要注意的一件事是,即使链接速度为 1 Gbits/sec(128MBps),但由于在操作系统上运行,我们永远不会直接获得相同的吞吐量。应用程序/内核延迟导致链接空闲,因此我们获得较少的吞吐量。

  1. Why do I need more than one process to use up the bandwidth?

    /proc/net/bonding/bond0  
    Bonding Mode: IEEE 802.3ad Dynamic link aggregation
    Transmit Hash Policy: layer3+4 (1)

如绑定(bind)接口(interface)信息中所述,拾取一个从站取决于 L3 header (IP src 和 dst)和 L4 header (src 和 dst 端口)。在您运行多个客户端应用程序的情况下,您实际上使用不同的 src 端口,因此可能会选择不同的从站,这与拥有单个应用程序的情况不同。检查这个wiki用于传输哈希策略。

  1. Why does the theory value not result in the best throughput (117 MB/s)?

如前所述,在操作系统上运行时很难获得链接速度。尝试使用 UDP 而不是 TCP,您可以看到您更接近链接速度。 TCP 具有较低的吞吐量,因为 TCP 是可靠的,因此缓存数据,有时依赖于定时器触发器(低频定时器)来传输数据包。尝试使用 TCP_NODELAY 选项要求 tcp 堆栈在应用程序调用 sendmsg() 后立即发送数据你也可以试试 iperf测量 TCP/UDP 吞吐量的应用程序,它具有在同一套接字上运行多个线程的选项。

  1. Why is the best result (51.5 MB/s) still not as good as the result of kernel autotuning (117 MB/s)?

不确定,但可能是因为,我看到内核通过调用 tcp_sndbuf_expand() 调整 sk_sndbuf通常基于服务器传播的 TCP 窗口大小。因此它会根据指标(如拥塞、服务器处理时间等)不断更改 sndbuf 大小

关于TCP 缓冲区大小和以太网绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34133568/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com