搜索

34.6. 调优 UDP 连接

download PDF

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

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

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

34.6.2. 使用 iperf3 测试 UDP 吞吐量

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

注意

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

先决条件

  • 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 标头(20 字节用于 IPv4 ,40 字节用于 IPv6) - 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) 手册页

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

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

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

重要

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

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

  • 以太网 :MTU 限制为 9000 字节。
  • 数据报模式下的 IP over InfiniBand (IPoIB):MTU 限制为比 InfiniBand MTU 少 4 个字节。
  • 内存网络通常支持大型 MTU。详情请查看相应的文档。

34.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,则相同的 CPU 将 40 GBit NIC 上的 UDP 流量限制在大约 20-25 Gbps。

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