搜索

31.6. 调优 UDP 连接

download PDF

在开始调优 Red Hat Enterprise Linux 以改进 UDP 流量的吞吐量之前,有一个现实的预期很重要。UDP 是一个简单协议。与 TCP 相比,UDP 不包含如,流控制、拥塞控制和数据可靠性等功能。这样很难在吞吐量率接近网络接口控制器(NIC)的最大速度的 UDP 上达到可靠的通信。

31.6.1. 检测数据包丢弃

在内核可以丢弃数据包的网络堆栈中有多个级别。Red Hat Enterprise Linux 提供了不同的工具来显示这些级别的统计信息。使用它们来识别潜在的问题。

请注意,您可以忽略非常小的数据包丢弃率。但是,如果您遇到非常大的丢失率,请考虑调优措施。

注意

如果网络堆栈无法处理传入的流量,则内核会丢弃网络数据包。

流程

  1. 确定网络接口控制器(NIC)是否丢弃了数据包:

    1. 显示 NIC 和特定于驱动程序的统计信息:

      # ethtool -S enp1s0
      NIC statistics:
           ...
           rx_queue_0_drops: 17657
           ...

      统计的命名以及其是否可用取决于 NIC 和驱动程序。

    2. 显示接口统计信息:

      # ip -s link show enp1s0
      2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
          link/ether 52:54:00:74:79:56 brd ff:ff:ff:ff:ff:ff
          RX:   bytes  packets errors dropped  missed   mcast_
          84697611107 56866482      0   10904       0       0
          TX:   bytes  packets errors dropped carrier collsns_
           5540028184  3722234      0       0       0       0

      RX 代表接收的数据包和传输的数据包 TX 的统计信息。

  2. 识别由于套接字缓冲太小,或者应用程序处理速度较慢导致的特定于 UDP 协议的数据包丢弃:

    # nstat -az UdpSndbufErrors UdpRcvbufErrors
    #kernel
    UdpSndbufErrors           4    0.0
    UdpRcvbufErrors    45716659    0.0

    输出中的第二列列出了计数。

31.6.2. 使用 iperf3 测试 UDP 吞吐量

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

注意

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

先决条件

  • iperf3 软件包安装在客户端和服务器上。
  • 两个主机上没有其他服务导致严重影响测试结果的网络流量。
  • 可选:增加服务器和客户端上最大 UDP 套接字大小。详情请参阅 增加系统范围的 UDP 套接字缓冲区

流程

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

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

    1. 显示最大 UDP 套接字读缓冲区大小,并记录值:

      # sysctl net.core.rmem_max
      net.core.rmem_max = 16777216

      显示的值以字节为单位。

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

      # firewall-cmd --add-port=5201/tcp --add-port=5201/udp
      # firewall-cmd --reload

      请注意,iperf3 只打开服务器上的一个 TCP 套接字。如果客户端希望使用 UDP,它首先连接到此 TCP 端口,然后服务器在同一端口号上打开一个 UDP 套接字,以执行 UDP 流量吞吐量测试。因此,您必须在本地防火墙中为 TCP 和 UDP 协议打开端口 5201。

    3. 在服务器模式下启动 iperf3

      # iperf3 --server

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

  3. 在客户端中:

    1. 显示客户端用于连接服务器的接口的最大传输单元(MTU),并记录值:

      # ip link show enp1s0
      2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
      ...
    2. 显示最大 UDP 套接字写缓冲区大小,并记录值:

      # sysctl net.core.wmem_max
      net.core.wmem_max = 16777216

      显示的值以字节为单位。

    3. 开始测量吞吐量:

      # iperf3 --udp --time 60 --window 16777216 --length 1472 --bitrate 2G --client 192.0.2.1
      • --udp :使用 UDP 协议进行测试。
      • --time <seconds>:定义客户端停止传输时的时间(以秒为单位)。
      • --window <size> :设置 UDP 套接字缓冲区大小。理想情况下,客户端和服务器上的大小相同。如果不同,则将此参数设置为:比客户端上的net.core.wmem_max或服务器上的 net.core.rmem_max 更小的值。
      • --length <size> :设置要读和写的缓冲区的长度。将这个选项设置为最大的未碎片的有效负载。按如下所示计算理想的值:MTU - IP 标头(IPv4 为 20 字节,IPv6 为 40 字节) - 8 字节 UDP 标头。
      • --bitrate <rate> :将比特率限制为指定的值,单位是比特每秒。您可以指定单位,如 2G 代表 2 Gbps。

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

      • --client <server> :启用客户端模式并设置运行 iperf3 服务器的服务器的 IP 地址或名称。
  4. 等待 iperf3 完成测试。服务器和客户端都显示每秒的统计信息,并在结尾显示总结。例如,以下是在客户端上显示的总结:

    [ ID] Interval       Transfer      Bitrate         Jitter    Lost/Total Datagrams
    [ 5] 0.00-60.00 sec  14.0 GBytes   2.00 Gbits/sec  0.000 ms  0/10190216 (0%) sender
    [ 5] 0.00-60.04 sec  14.0 GBytes   2.00 Gbits/sec  0.002 ms  0/10190216 (0%) receiver

    在这个示例中,平均比特率为 2 Gbps,没有丢失数据包。

  5. 在服务器中:

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

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

其他资源

  • iperf3 (1) 手册页

31.6.3. MTU 大小对 UDP 流量吞吐量的影响

如果您的应用程序使用大型 UDP 消息大小,则使用巨型帧可以提高吞吐量。根据 IEEE 802.3 标准,没有 Virtual Local Area Network (VLAN)标签的默认以太网帧最大大小为 1518 字节。这些帧的每一个都包含一个 18 字节标头,为有效负载保留 1500 字节。因此,对于服务器通过网络传输的每 1500 字节数据,有 18 字节(1.2%)是开销。

巨型帧是非标准帧,其比 1500 字节的标准以太网有效负载有更大的最大传输单位(MTU)。例如,如果您使用最大允许的 9000 字节有效负载的 MTU 配置巨型帧,则每个帧的开销减少到 0.2%。

重要

传输路径上的所有网络设备和涉及的广播域都必须支持巨型帧,并使用相同的 MTU。由于传输路径上的 MTU 设置不一致,所以数据包碎片和重组会减少网络吞吐量。

不同的连接类型有一些 MTU 限制:

  • Ethernet :MTU 限制为 9000 字节。
  • datagram 模式中的 IP over InfiniBand (IPoIB):MTU 限制为比 InfiniBand MTU 少 4 字节。
  • 内存网络通常支持更大的 MTU。详情请查看相应的文档。

31.6.4. CPU 速度对 UDP 流量吞吐量的影响

在批量传输中,UDP 协议比 TCP 效率要低得多,主要是因为 UDP 中缺少数据包聚合。默认情况下,不会启用 Generic Receive Offload (GRO)和 Transmit Segmentation Offload (TSO)功能。因此,对于高速链路上的批量传输,CPU 频率可能会限制 UDP 吞吐量。

例如,在具有高最大传输单元(MTU)和大型套接字缓冲区的调优的主机上,3 GHz CPU 可以处理全速发送或接收 UDP 流量的 10 GBit NIC 的流量。但是,当您传输 UDP 流量时,您可以预计在 3 GHz 下,每 100 MHz CPU 速度会损失大约 1-2 Gbps 速度。另外,如果 3 GHz 的 CPU 速度可以达到接近 10 Gbps,则在 40 GBit NIC 上,相同的 CPU 将 UDP 流量限制为大约 20-25 Gbps。

31.6.5. 增加系统范围的 UDP 套接字缓冲区

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

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

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

重要

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

先决条件

  • 您遇到了明显的 UDP 数据包丢弃率。

流程

  1. 根据您的要求,创建 /etc/sysctl.d/10-udp-socket-buffers.conf 文件,并设置最大读或写缓冲区大小,或两个都设置:

    net.core.rmem_max = 16777216
    net.core.wmem_max = 16777216

    指定值(以字节为单位)。本例中的值将缓冲区的最大大小设置为 16 MiB。这两个参数的默认值都为 212992 字节(208 KiB)。

  2. /etc/sysctl.d/10-udp-socket-buffers.conf 文件中载入设置:

    # sysctl -p /etc/sysctl.d/10-udp-socket-buffers.conf
  3. 将应用程序配置为使用更大的套接字缓冲大小。

    net.core.rmem_maxnet.core.wmem_max 参数定义应用程序中 setsockopt() 函数可以请求的最大缓冲区大小。请注意,如果您将应用程序配置为不使用 setsockopt() 函数,则内核将使用 rmem_defaultwmem_default 参数的值。

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

  4. 重启应用程序以使用新的 UDP 缓冲区大小。

验证

  • 使用您在遇到数据包丢弃时使用的相同方法来监控数据包丢弃统计信息。

    如果数据包仍然以较低的速率发生,请进一步增加缓冲区大小。

其他资源

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.