如何提高 Linux balance-rr bonds 和/或 FreeBSD roundrobin laggs 中 TCP 对无序传送的容忍度?

如何提高 Linux balance-rr bonds 和/或 FreeBSD roundrobin laggs 中 TCP 对无序传送的容忍度?

我有 3 个服务器网络配置如下

  • A是一台运行 Linux 5.13.19-1-pve 的 DELL R710Proxmox VE 7.1并且4 个 NIC 以balance-rr模式绑定
  • 是一台运行 Linux 5.13.19-1-pve 的 DELL R610Proxmox VE 7.1并且4 个 NIC 以balance-rr模式绑定
  • C是运行FreeBSD 12.2-RELEASE-p1超过 8 个 NIC 时会滞后roundrobin(这是 TrueNAS 发行版)

所有 NIC 均为 1 GBps。

当我在 Linux 刀片之间运行时iperf3,我的最大速度约为 3 GBps,窗口平均上升到 ~300 KiB。但是,在 TrueNAS (FreeBSD) 刀片和 Linux 刀片之间,TCP 流的最大速度为 1.20 Gbps,窗口平均上限为 ~60 KiB。如果我运行并行流(即iperf3 ... -P 8),我可以使绑定饱和。另一方面,正如预期的那样,在这两种情况下,重新传输次数都相当高。所以,我的问题是,

  1. 如果假设两者以相同的方式处理问题,那么为什么 FreeBSD 却无法达到相同的吞吐量?(也许我错了)。
  2. 是否有一个调整选项或选项组合可以使 TCP 堆栈对无序更加宽容,而不会触发立即重新传输?(我对 3-ACK reTX、TCP 拥塞控制基础知识等有点熟悉)。

我将在这里列出我在测试期间使用过的一些可调参数和选项。

  • 所有 iface 都设置为使用巨型帧 (MTU 9000)。
  • Linux 系统调优如下
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.ipv4.tcp_mem = 1638400 1638400 1638400
net.ipv4.tcp_rmem = 10240 87380 16777216
net.ipv4.tcp_rmem = 10240 87380 16777216
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_reordering = 127
net.ipv4.tcp_max_reordering = 1000
net.core.netdev_max_backlog = 10000
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_congestion_control = reno
  • FreeBSD (TrueNAS Core ~= FreeNAS) 盒的调整如下
kern.ipc.maxsockbuf=614400000
kern.ipc.somaxconn=1024
net.route.netisr_maxqlen=8192
net.inet.ip.intr_queue_maxlen=8192
net.inet.tcp.mssdflt=8948
net.inet.tcp.reass.maxqueuelen=1000
net.inet.tcp.recvbuf_inc=65536
net.inet.tcp.sendbuf_inc=65536
net.inet.tcp.sendbuf_max=307200000
net.inet.tcp.recvbuf_max=307200000
net.inet.tcp.recvspace=65228
net.inet.tcp.sendspace=65228
net.inet.tcp.minmss=536
net.inet.tcp.abc_l_var=52
net.inet.tcp.initcwnd_segments=52 # start fast
net.inet.udp.recvspace=1048576
net.inet.udp.sendspace=1048576

答案1

如果您的网络支持,您可以尝试使用巨型帧。它不会消除触发 TCP 无序重传的主要问题。但是,由于以太网帧大六倍,数据包数量会减少,从而减少无序事件的数量。

否则,您应该检查您的用例,您是否真的需要单个 TCP 连接来获得整个吞吐量?如果设备之间有多个活动的 TCP 连接,那么您应该使用 TCP 感知负载平衡。

相关内容