搜索

34.5. 为高吞吐量调优 TCP 连接

download PDF

在 Red Hat Enterprise Linux 上调优与 TCP 相关的设置以提高吞吐量、缩短延迟或防止诸如数据包丢失等问题。

34.5.1. 使用 iperf3 测试 TCP 吞吐量

iperf3 工具提供了服务器和客户端模式,来在两个主机之间执行网络吞吐量测试。

注意

应用程序的吞吐量取决于许多因素,如应用程序使用的缓冲区大小。因此,测试工具(如 iperf 3)测量的结果可能与生产工作负载下服务器上应用程序的测量结果有很大不同。

先决条件

  • iperf3 软件包已安装在客户端和服务器上。
  • 任何一个主机上都没有其他服务导致对测试结果产生严重影响的网络流量。
  • 对于 40 Gbps 和更快的连接,网卡支持 Accelerated Receive Flow Steering(ARFS),且该功能在接口上已启用。

流程

  1. 可选:显示服务器和客户端上网络接口控制器(NIC)的最大网络速度:

    # ethtool enp1s0 | grep "Speed"
       Speed: 100000Mb/s
  2. 在服务器中:

    1. 临时在 firewalld 服务中打开默认的 iperf3 TCP 端口 5201 :

      # firewall-cmd --add-port=5201/tcp
      # firewall-cmd --reload
    2. 在服务器模式下启动 iperf3

      # iperf3 --server

      服务现在等待传入的客户端连接。

  3. 在客户端中:

    1. 开始测量吞吐量:

      # iperf3 --time 60 --zerocopy --client 192.0.2.1
      • --time <seconds> :定义客户端停止传输时的时间(以秒为单位)。

        将此参数设置为您希望工作的值,并在稍后的测量中增加它。如果服务器发送数据包的速度比传输路径上的设备或者客户端可以处理的速度快,则数据包可能被丢弃。

      • --zerocopy :启用零复制方法,而不是使用 write() 系统调用。只有在您要模拟可零复制的应用程序或在单个流上达到 40 Gbps 及更多时,才需要这个选项。
      • --client <server>:启用客户端模式,并设置运行 iperf3 服务器的服务器的 IP 地址或名称。
  4. 等待 iperf3 完成测试。服务器和客户端都显示每秒的统计信息,并在结尾显示总结。例如,以下是客户端上显示的总结:

    [ ID] Interval         Transfer    Bitrate         Retr
    [  5] 0.00-60.00  sec  101 GBytes   14.4 Gbits/sec   0   sender
    [  5] 0.00-60.04  sec  101 GBytes   14.4 Gbits/sec       receiver

    在这个示例中,平均比特率为 14.4 Gbps。

  5. 在服务器中:

    1. Ctrl+C 停止 iperf3 服务器。
    2. 关闭 firewalld 中的 TCP 端口 5201:

      # firewall-cmd --remove-port=5201/tcp
      # firewall-cmd --reload

其他资源

  • iperf3 (1) 手册页

34.5.2. 系统范围的 TCP 套接字缓冲区设置

套接字缓冲区临时存储内核已收到的或应发送的数据:

  • 读套接字缓冲区保留内核已收到的,但应用程序尚未读取的数据包。
  • 写套接字缓冲区保留应用程序已写到缓冲区,但内核尚未传给 IP 堆栈和网络驱动程序的数据包。

如果 TCP 数据包太大,且超过缓冲区大小或数据包以太快的速度发送或接收,则内核会丢弃任何新传入的 TCP 数据包,直到数据从缓冲区中删除为止。在这种情况下,增加套接字缓冲区可以阻止数据包丢失。

net.ipv4.tcp_rmem(读)和 net.ipv4.tcp_wmem(写)套接字缓冲区内核设置包含三个值:

net.ipv4.tcp_rmem = 4096  131072  6291456
net.ipv4.tcp_wmem = 4096  16384   4194304

显示的值以字节为单位,Red Hat Enterprise Linux 以以下方法使用它们:

  • 第一个值是最小缓冲区大小。新套接字不能有更小的大小。
  • 第二个值是默认的缓冲区大小。如果应用程序没有设置缓冲区大小,则这是默认值。
  • 第三个值是自动调优的缓冲区的最大大小。在应用程序中使用带有 SO_SNDBUF 套接字选项的 setsockopt() 函数可禁用这个最大缓冲区大小。

请注意,net.ipv4.tcp_rmemnet.ipv4.tcp_wmem 参数为 IPv4 和 IPv6 协议设置套接字大小。

34.5.3. 增加系统范围的 TCP 套接字缓冲区

系统范围的 TCP 套接字缓冲区临时存储内核已接收或应发送的数据。net.ipv4.tcp_rmem(读)和 net.ipv4.tcp_wmem(写)套接字缓冲区内核设置各自包含三个设置:最小值、默认值和最大值。

重要

设置太大的缓冲区大小浪费内存。每个套接字可以设置为应用程序请求的大小,内核会加倍这个值。例如,如果应用程序请求 256 KiB 套接字缓冲区大小,并打开 100 万个套接字,则系统只能将最多 512 GB RAM (512 KiB x 100万)用于潜在的套接字缓冲空间。

另外,最大缓冲区大小的值太大可能会增加延迟。

先决条件

  • 您遇到了大量的 TCP 数据包丢包率。

流程

  1. 确定连接的延迟。例如,从客户端 ping 服务器来测量平均 Round Trip Time (RTT):

    # ping -c 10 server.example.com
    ...
    --- server.example.com ping statistics ---
    10 packets transmitted, 10 received, 0% packet loss, time 9014ms
    rtt min/avg/max/mdev = 117.208/117.056/119.333/0.616 ms

    在本例中,延迟为 117 ms。

  2. 使用以下公式为您要调优的流量计算 Bandwidth Delay Product(BDP):

    connection speed in bytes * latency in ms = BDP in bytes

    例如,要计算具有 117 ms 延迟的 10 Gbps 连接的 BDP:

    (10 * 1000 * 1000 * 1000 / 8) * 117 = 10683760 bytes
  3. 根据您的要求,创建 /etc/sysctl.d/10-tcp-socket-buffers.conf 文件,并设置最大读或写缓冲区大小,或者两者:

    net.ipv4.tcp_rmem = 4096 262144 21367520
    net.ipv4.tcp_wmem = 4096 24576 21367520

    指定以字节为单位的值。当您尝试识别为您的环境优化的值时,请使用以下经验法则:

    • 默认缓冲区大小(第二个值):仅稍微增加此值或将其最多设为 524288 (512 KiB)。太高的默认缓冲区大小可能会导致缓冲区崩溃,因此延迟激增。
    • 最大缓冲区大小(第三个值):两到三倍 BDP 的值通常就足够了。
  4. /etc/sysctl.d/10-tcp-socket-buffers.conf 文件载入设置:

    # sysctl -p /etc/sysctl.d/10-tcp-socket-buffers.conf
  5. 配置应用程序以使用更大的套接字缓冲区大小。net.ipv4.tcp_rmemnet.ipv4.tcp_wmem 参数中的第三个值定义应用程序中 setsockopt() 函数可以请求的最大缓冲区大小。

    详情请查看应用程序的编程语言的文档。如果您不是应用的开发人员,请联系开发人员。

  6. 如果您已更改了 net.ipv4.tcp_rmemnet.ipv4.tcp_wmem 参数中的第二个值,请重启应用程序以使用新的 TCP 缓冲区大小。

    如果您只更改了第三个值,则不需要重启应用程序,因为自动调优会动态应用这些设置。

验证

  1. 可选:使用 iperf3 测试 TCP 吞吐量
  2. 使用与您遇到数据包丢弃时相同的方法来监控数据包丢弃统计信息。

    如果数据包丢弃仍然发生,但比率较低,请进一步增加缓冲区大小。

其他资源

34.5.4. TCP 窗口扩展

在 Red Hat Enterprise Linux 中默认启用的 TCP 窗口扩展功能是 TCP 协议的扩展,它显著提高了吞吐量。

例如,在具有 1.5 ms Round Trip Time (RTT)的 1 Gbps 连接上:

  • 启用 TCP 窗口扩展后,大约 630 Mbps 是可行的。
  • 禁用 TCP 窗口扩展后,吞吐量会下降到 380 Mbps。

TCP 提供的一个功能是流控制。通过流控制,发送方可以发送接收方可以接收的尽可能多的数据,但不能发送太多。为此,接收方通告一个 window 值,这是发送方可以发送的数据量。

TCP 最初支持最多 64 KiB 的窗口大小,但对于高 Bandwidth Delay Products(BDP),这个值变为一个限制,因为发送方一次不能发送超过 64 KiB 的数据。高速连接可以在给定时间内传输超过 64 KiB 的数据。例如:一个在系统之间有 1 毫秒延迟的 10 Gbps 链接,在给定时间内可以传输超过 1 MiB 的数据。如果主机只发送 64 KiB,然后暂停,直到其他主机收到这 64 KiB,则这将是低效的。

要删除这个瓶颈,TCP 窗口扩展扩展允许 TCP 窗口值算术左移,来将窗口大小增加到 64 KiB 以上。例如,最大窗口值 65535 向左移 7 个位置,会产生几乎 8 MiB 的窗口大小。这可在给定时间内传输更多的数据。

TCP 窗口扩展在打开每个 TCP 连接的三向 TCP 握手中进行协商。发件方和接收方都必须支持 TCP 窗口扩展,才能使其正常工作。如果两个参与者没有在握手中通告窗口扩展功能,则连接恢复为使用最初的 16 位 TCP 窗口大小。

默认情况下,TCP 窗口扩展在 Red Hat Enterprise Linux 中被启用:

# sysctl net.ipv4.tcp_window_scaling
net.ipv4.tcp_window_scaling = 1

如果在服务器上禁用了 TCP 窗口扩展(0),则以与您设置它的相同方式恢复设置。

34.5.5. TCP SACK 如何降低数据包丢弃率

在 Red Hat Enterprise Linux (RHEL)中默认启用的 TCP Selective Acknowledgment(TCP SACK)功能是 TCP 协议的一种改进,提高了 TCP 连接的效率。

在 TCP 传输中,对于其接收的每个数据包,接收方都向发送方发送一个 ACK 数据包。例如,客户端向服务器发送 TCP 数据包 1-10,但数据包号 5 和 6 丢失了。如果没有 TCP SACK,服务器会丢弃数据包 7-10,客户端必须从丢失点重传所有数据包,这效率较低。如果两个主机上都启用了 TCP SACK,则客户端必须只重传丢失的数据包 5 和 6。

重要

禁用 TCP SACK 会降低性能,并在 TCP 连接中,在接收端造成很高的数据包丢弃率。

RHEL 中默认启用了 TCP SACK。要验证:

# sysctl net.ipv4.tcp_sack
1

如果在您的服务器上禁用了 TCP SACK (0),请以与您设置它的相同方式恢复设置。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.