34.9. 避免侦听队列锁争用


队列锁争用可能导致数据包丢弃和更高的 CPU 使用率,因此导致更高的延迟。您可以通过调优应用程序并使用传输数据包控制,来避免接收(RX)和传输(TX)队列上的队列锁争用。

在多核系统上,如果应用程序使用 SO_REUSEPORTSO_REUSEPORT_BPF 套接字选项打开了端口,您可以提高多线程网络服务器应用程序的性能。如果应用程序不使用其中一个套接字选项,则所有线程都被强制共享单个套接字来接收传入流量。使用单个套接字会导致:

  • 对接收缓冲区的显著竞争,这可能会导致数据包丢弃和更高的 CPU 使用率。
  • CPU 使用率的显著增加
  • 可能的数据包丢弃

使用 SO_REUSEPORTSO_REUSEPORT_BPF 套接字选项,一个主机上的多个套接字可以绑定到同一端口:

Red Hat Enterprise Linux 提供了一个如何在内核源中使用 SO_REUSEPORT 套接字选项的代码示例。要访问代码示例:

  1. 启用 rhel-8-for-x86_64-baseos-debug-rpms 存储库:

    # subscription-manager repos --enable rhel-8-for-x86_64-baseos-debug-rpms
    Copy to Clipboard Toggle word wrap
  2. 安装 kernel-debuginfo-common-x86_64 软件包:

    # yum install kernel-debuginfo-common-x86_64
    Copy to Clipboard Toggle word wrap
  3. 代码示例现在在 /usr/src/debug/kernel-<version>/linux-<version>/tools/testing/selftests/net/reuseport_bpf_cpu.c 文件中。

34.9.2. 避免 TX 队列锁争用:传输数据包控制

在具有支持多个队列的网络接口控制器(NIC)的主机中,传输数据包控制(XPS)将传出网络数据包的处理分发到多个队列。这可让多个 CPU 处理传出网络流量,并避免传输队列锁争用,从而避免数据包丢弃。

某些驱动程序,如 ixgbei40emlx5 会自动配置 XPS。要识别驱动程序是否支持此功能,请咨询 NIC 驱动程序文档。请咨询您的 NIC 驱动程序文档来识别驱动程序是否支持此功能。如果驱动程序不支持 XPS 自动调优,您可以手动将 CPU 核分配给传输队列。

注意

Red Hat Enterprise Linux 不提供一个将传输队列永久分配给 CPU 核的选项。使用在接口被激活时执行的 NetworkManager 分配程序脚本中的命令。详情请参阅 如何编写一个 NetworkManager 分配程序脚本,以便在接口启动时应用命令

先决条件

  • NIC 支持多个队列。
  • numactl 软件包已安装。

流程

  1. 显示可用队列的数量:

    # ethtool -l enp1s0
    Channel parameters for enp1s0:
    Pre-set maximums:
    RX:		0
    TX:		0
    Other:		0
    Combined:	4
    Current hardware settings:
    RX:		0
    TX:		0
    Other:		0
    Combined:	1
    Copy to Clipboard Toggle word wrap

    Pre-set maximums 部分显示队列的总数,Current hardware settings 显示当前分配给接收、传输、其他或组合队列的队列数。

  2. 可选:如果您需要特定通道上的队列,请相应地分配它们。例如,要将 4 个队列分配给 Combined 通道,请输入:

    # ethtool -L enp1s0 combined 4
    Copy to Clipboard Toggle word wrap
  3. 显示 NIC 被分配给了哪个 Non-Uniform Memory Access (NUMA)节点:

    # cat /sys/class/net/enp1s0/device/numa_node
    0
    Copy to Clipboard Toggle word wrap

    如果文件未找到,或者命令返回 -1, 则主机不是 NUMA 系统。

  4. 如果主机是 NUMA 系统,显示哪些 CPU 被分配给了哪个 NUMA 节点:

    # lscpu | grep NUMA
    NUMA node(s):       2
    NUMA node0 CPU(s):  0-3
    NUMA node1 CPU(s):  4-7
    Copy to Clipboard Toggle word wrap
  5. 在上例中,NIC 有 4 个队列,NIC 被分配给 NUMA 节点 0。此节点使用 CPU 核 0-3。因此,将每个传输队列映射到 CPU 核 0-3 中的一个:

    # echo 1 > /sys/class/net/enp1s0/queues/tx-0/xps_cpus
    # echo 2 > /sys/class/net/enp1s0/queues/tx-1/xps_cpus
    # echo 4 > /sys/class/net/enp1s0/queues/tx-2/xps_cpus
    # echo 8 > /sys/class/net/enp1s0/queues/tx-3/xps_cpus
    Copy to Clipboard Toggle word wrap

    如果 CPU 核数和传输(TX)队列相同,请使用 1 对 1 映射,以避免 TX 队列上的任何类型的争用。否则,如果您在同一 TX 队列上映射多个 CPU,则不同 CPU 上的传输操作将导致 TX 队列锁竞争,并对传输吞吐量造成负面影响。

    请注意,您必须将包含 CPU 核号的位图传给队列。使用以下命令计算位图:

    # printf %x $((1 << <core_number> ))
    Copy to Clipboard Toggle word wrap

验证

  1. 识别发送流量的服务的进程 ID (PID):

    # pidof <process_name>
    12345 98765
    Copy to Clipboard Toggle word wrap
  2. 将 PID 固定到使用 XPS 的核:

    # numactl -C 0-3 12345 98765
    Copy to Clipboard Toggle word wrap
  3. 在进程发送流量时监控 requeues 计数器:

    # tc -s qdisc
    qdisc fq_codel 0: dev enp10s0u1 root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
     Sent 125728849 bytes 1067587 pkt (dropped 0, overlimits 0 requeues 30)
     backlog 0b 0p requeues 30
     ...
    Copy to Clipboard Toggle word wrap

    如果 requeues 计数器不再以显著速率增加,则 TX 队列锁争用不再发生。

使用高速度 UDP 批量传输的应用程序应该在 UDP 套接字上启用和使用 UDP Generic Receive Offload (GRO)。但是,如果满足以下条件,您可以禁用 GRO 来提高吞吐量:

  • 应用程序不支持 GRO,且无法添加该功能。
  • TCP 吞吐量不相关。

    警告

    禁用 GRO 可显著降低 TCP 流量的接收吞吐量。因此,不要在与 TCP 性能相关的主机上禁用 GRO。

先决条件

  • 主机主要处理 UDP 流量。
  • 应用程序不使用 GRO。
  • 主机不使用 UDP 隧道协议,如 VXLAN。
  • 主机不运行虚拟机(VM)或容器。

流程

  1. 可选:显示 NetworkManager 连接配置文件:

    # nmcli connection show
    NAME     UUID                                  TYPE      DEVICE
    example  f2f33f29-bb5c-3a07-9069-be72eaec3ecf  ethernet  enp1s0
    Copy to Clipboard Toggle word wrap
  2. 在连接配置文件中禁用 GRO 支持:

    # nmcli connection modify example ethtool.feature-gro off
    Copy to Clipboard Toggle word wrap
  3. 重新激活连接配置文件:

    # nmcli connection up example
    Copy to Clipboard Toggle word wrap

验证

  1. 验证 GRO 是否已禁用:

    # ethtool -k enp1s0 | grep generic-receive-offload
    generic-receive-offload: off
    Copy to Clipboard Toggle word wrap
  2. 监控服务器上的吞吐量。如果设置对主机上的其他应用程序有负面影响,请在 NetworkManager 配置文件中重新启用 GRO。
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2025 Red Hat