第 34 章 调优网络性能
调优网络设置是一个复杂的进程,有很多因素需要考虑。例如,这包括 CPU 到内存架构、CPU 核数等。Red Hat Enterprise Linux 使用针对大多数场景优化的默认设置。然而,在某些情况下,有必要调优网络设置,以提高吞吐量或延迟或解决问题,如数据包丢弃。
34.1. 调优网络适配器设置
在 40 Gbps 及更快的高速网络中,一些与网络适配器相关的内核设置的默认值可能是数据包丢弃和性能降低的原因。调优这些设置可能会阻止此类问题发生。
34.1.1. 使用 nmcli
增加环缓冲区的大小,以减少该数据包丢弃率
如果数据包丢包率导致应用程序报告数据丢失、超时或其他问题,请增加以太网设备的环缓冲的大小。
接收环缓冲在设备驱动程序和网络接口控制器(NIC)之间共享。该卡分配一个传输(TX)和接收(RX)环缓冲。名称意味着,环缓冲是循环缓冲区,溢出会覆盖现有数据。可以通过两种方法将数据从 NIC 移至内核,硬件中断和软件中断也称为 SoftIRQ。
内核使用 RX 环缓冲区来存储传入的数据包,直到设备驱动程序可以处理它们。设备驱动程序排空 RX 环,通常是使用 SoftIRQ,其将传入的数据包放在名为 sk_buff
或 skb
的内核数据结构中,以通过内核开始其过程,直到拥有相关套接字的应用程序。
内核使用 TX 环缓冲区来存放应发送到网络的传出数据包。这些环缓冲区位于堆栈的底部,是可能发生数据包丢弃的关键点,这反过来会对网络性能造成负面影响。
流程
显示接口的数据包丢包统计信息:
# ethtool -S enp1s0 ... rx_queue_0_drops: 97326 rx_queue_1_drops: 63783 ...
请注意,命令的输出取决于网卡和驱动程序。
discard
或drop
计数器中的高值表示可用缓冲区的填满速度快于内核可以处理数据包的速度。增加环缓冲有助于避免此类丢失。显示最大环缓冲大小:
# ethtool -g enp1s0 Ring parameters for enp1s0: Pre-set maximums: RX: 4096 RX Mini: 0 RX Jumbo: 16320 TX: 4096 Current hardware settings: RX: 255 RX Mini: 0 RX Jumbo: 0 TX: 255
如果
Pre-set maximums
部分中的值大于Current hardware settings
部分的值,您可以在下一步中更改设置。确定使用接口的 NetworkManager 连接配置文件:
# nmcli connection show NAME UUID TYPE DEVICE Example-Connection a5eb6490-cc20-3668-81f8-0314a27f3f75 ethernet enp1s0
更新连接配置文件,并增加环缓冲:
要增加 RX 环缓冲区,请输入:
# nmcli connection modify Example-Connection ethtool.ring-rx 4096
要增加 TX 环缓冲区,请输入:
# nmcli connection modify Example-Connection ethtool.ring-tx 4096
重新载入 NetworkManager 连接:
# nmcli connection up Example-Connection
重要根据 NIC 使用的驱动程序,环缓冲中的更改可能会短暂中断网络连接。
其他资源
- ifconfig 和 ip 命令报告数据包丢弃
- 我是否应该关注 0.05% 的数据包丢弃率?
-
ethtool(8)
手册页
34.1.2. 调优网络设备积压队列以避免数据包丢弃
当网卡接收数据包并在内核协议堆栈处理它们之前,内核会将这些数据包存储在积压队列中。内核为每个 CPU 核维护一个单独的队列。
如果核的积压队列满了,则内核会丢弃将来 netif_receive_skb()
内核函数分配给此队列的所有传入的数据包。如果服务器包含 10 Gbps 或更快的网络适配器或多个 1 Gbps 适配器,请调优积压队列大小,以避免此问题发生。
前提条件
- 一个 10 Gbps 或更快或多个 1 Gbps 网络适配器
流程
确定是否需要调整积压队列,显示
/proc/net/softnet_stat
文件中的计数器:# awk '{for (i=1; i<=NF; i++) printf strtonum("0x" $i) (i==NF?"\n":" ")}' /proc/net/softnet_stat | column -t 221951548 0 0 0 0 0 0 0 0 0 0 0 0 192058677 18862 0 0 0 0 0 0 0 0 0 0 1 455324886 0 0 0 0 0 0 0 0 0 0 0 2 ...
此
awk
命令将/proc/net/softnet_stat
中的值从十六进制转换为十进制格式,并以表格式显示它们。每行代表核 0 开始的 CPU 核。相关的列有:
- 第一列:收到的总帧数
- 第二列:由于积压队列满了而丢弃的帧数
- 最后一列:CPU 核数
如果
/proc/net/softnet_stat
文件的第二列中的值随着时间而递增,请增加积压队列的大小:显示当前积压队列大小:
# sysctl net.core.netdev_max_backlog net.core.netdev_max_backlog = 1000
使用以下内容创建
/etc/sysctl.d/10-netdev_max_backlog.conf
文件:net.core.netdev_max_backlog = 2000
将
net.core.netdev_max_backlog
参数设置为当前值的两倍。从
/etc/sysctl.d/10-netdev_max_backlog.conf
文件中载入设置:# sysctl -p /etc/sysctl.d/10-netdev_max_backlog.conf
验证
监控
/proc/net/softnet_stat
文件中的第二列:# awk '{for (i=1; i<=NF; i++) printf strtonum("0x" $i) (i==NF?"\n":" ")}' /proc/net/softnet_stat | column -t
如果值还在增加,请再次加倍
net.core.netdev_max_backlog
值。重复此过程,直到数据包丢弃计数不再增加。
34.1.3. 增加 NIC 的传输队列长度,以减少传输错误数
内核在传输数据包前,将它们存储在传输队列中。默认长度(1000 个数据包)通常对于 10 Gbps 足够了,通常对于 40 Gbps 网络也足够了。但是,在更快的网络中,或者遇到适配器上传输错误数增加,请增加队列长度。
流程
显示当前传输队列长度:
# 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 ...
在本例中,
enp1s0
接口的传输队列长度(qlen
)是1000
。监控网络接口的软件传输队列丢弃的数据包计数:
# tc -s qdisc show dev enp1s0 qdisc fq_codel 0: root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 Sent 16889923 bytes 426862765 pkt (dropped 191980, overlimits 0 requeues 2) ...
如果您遇到较高或不断增加的传输错误计数,请设置更高的传输队列长度:
识别使用此接口的 NetworkManager 连接配置文件:
# nmcli connection show NAME UUID TYPE DEVICE Example-Connection a5eb6490-cc20-3668-81f8-0314a27f3f75 ethernet enp1s0
使用以下内容创建
/etc/NetworkManager/dispatcher.d/99-set-tx-queue-length-up
NetworkManager 分配程序脚本:#!/bin/bash # Set TX queue length on enp1s0 to 2000 if [ "$1" == "enp1s0" ] && [ "$2" == "up" ] ; then ip link set dev enp1s0 txqueuelen 2000 fi
在
/etc/NetworkManager/dispatcher.d/99-set-tx-queue-length-up
文件上设置可执行位:# chmod +x /etc/NetworkManager/dispatcher.d/99-set-tx-queue-length-up
应用更改:
# nmcli connection up Example-Connection
验证
显示传输队列长度:
# ip -s link show enp1s0 2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 2000 ...
监控丢弃的数据包计数:
# tc -s qdisc show dev enp1s0
如果
丢弃
的计数还在增加,请再次加倍传输队列长度。重复此过程,直到计数不再增加。