我们有一台运行 RHEL 6.10 和 2 X 的 HP ProLiant DL360 G9。HPIntel 82599ES 10-Gigabit SFI/SFP+
产品名称是HP Ethernet 10Gb 2-port 560SFP+ Adapter
eth5
并eth6
显示大量数据包丢失(rx_missed_errors
)我在 NIC 级别禁用了流量控制,然后rx_missed_errors
停止了增加,但rx_no_dma_resources
每天开始增加。
- 它们都是独立的接口,不属于绑定的一部分。
- Eth5 和 eth6 位于不同的卡上
- 两张卡均安装在 PCIe 3.0 X16 插槽上
- irqbalance 正在服务器上运行
更新 1
eth5
和的环参数eth6
相同且已达到最大值。
Pre-set maximums:
RX: 4096
RX Mini: 0
RX Jumbo: 0
TX: 4096
Current hardware settings:
RX: 4096
RX Mini: 0
RX Jumbo: 0
TX: 4096
我注意到eth6
在/proc/interrupts
Sun Jun 2 19:39:42 EDT 2019
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 CPU8 CPU9 CPU10 CPU11 CPU12 CPU13 CPU14 CPU15 CPU16 CPU17 CPU18 CPU19
165: 0 0 0 0 0 484430 111744 333783 458868 577617 0 0 0 0 0 17978 402211 84832 183482 10567190 PCI-MSI-edge eth6-TxRx-0
166: 0 0 0 0 0 92569 2522312 36248 19459 1970 0 0 0 0 0 10140 33710 10180 1071214 651534 PCI-MSI-edge eth6-TxRx-1
167: 0 0 0 0 0 41060 2532170 37345 10970 92570 0 0 0 0 0 3055 22158 12485 1203344 494179 PCI-MSI-edge eth6-TxRx-2
168: 0 0 0 0 0 218925 8555 2312817 115650 126113 0 0 0 0 0 14575 3965 114145 995924 538667 PCI-MSI-edge eth6-TxRx-3
169: 0 0 0 0 0 7354 7781 199591 2262057 45221 0 0 0 0 0 34813 176350 105008 649389 962393 PCI-MSI-edge eth6-TxRx-4
170: 0 0 0 0 0 27982 23890 44703 162340 2597754 0 0 0 0 0 25991 22873 11846 885511 943057 PCI-MSI-edge eth6-TxRx-5
171: 0 0 0 0 0 16710 370 155 17725587 7504781 0 0 0 0 0 1054801625 1644839 14655 583745291 266971465 PCI-MSI-edge eth6-TxRx-6
172: 0 0 0 0 0 9823 6688 407394 11207 44103 0 0 0 0 0 88057 2496075 9284 56799 1391075 PCI-MSI-edge eth6-TxRx-7
173: 0 0 0 0 0 21175 1995 125490 151465 27120 0 0 0 0 0 19960 177195 2288457 787724 848755 PCI-MSI-edge eth6-TxRx-8
174: 0 0 0 0 0 7835 2210 3990 56075 106870 0 0 0 0 0 109740 24135 27720 2599827 1510934 PCI-MSI-edge eth6-TxRx-9
175: 0 0 0 0 0 42450 2605 39545 54520 162830 0 0 0 0 0 56035 11380 33815 52905 3993251 PCI-MSI-edge eth6-TxRx-10
176: 0 0 0 0 0 92335 33470 2290862 7545 227035 0 0 0 0 0 7550 25460 17225 65205 1682649 PCI-MSI-edge eth6-TxRx-11
177: 0 0 0 0 0 81685 56468 2273033 264820 195585 0 0 0 0 0 120640 36250 29450 244895 1146510 PCI-MSI-edge eth6-TxRx-12
178: 0 0 0 0 0 39655 24693 703993 1680384 22325 0 0 0 0 0 147980 27170 41585 72085 1689466 PCI-MSI-edge eth6-TxRx-13
179: 0 0 0 0 0 108905 1335 48265 2415832 19985 0 0 0 0 0 3545 23360 12590 35185 1780334 PCI-MSI-edge eth6-TxRx-14
180: 0 0 0 0 0 134826 291569 98014 9159 2262093 0 0 0 0 0 128867 18499 20078 39858 1463678 PCI-MSI-edge eth6-TxRx-15
181: 0 0 0 0 0 3220 37430 39030 129550 11070 0 0 0 0 0 2382452 24840 10860 146795 1664089 PCI-MSI-edge eth6-TxRx-16
182: 0 0 0 0 0 23120 28700 134025 96455 31545 0 0 0 0 0 30340 2262857 24485 144620 1673189 PCI-MSI-edge eth6-TxRx-17
183: 0 0 0 0 0 8900 29070 22490 112785 186240 0 0 0 0 0 40690 31665 2274862 37160 1705474 PCI-MSI-edge eth6-TxRx-18
184: 0 0 0 0 0 77090 18270 68465 53235 142648 0 0 0 0 0 16295 33770 29175 2367462 1642926 PCI-MSI-edge eth6-TxRx-19
185: 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 0 0 0 4 PCI-MSI-edge eth6
因此看起来 CPU/核心 15/18/19 在处理 eth6 上的流量时承受着压力
基本上我不知道下一步该看哪里,我猜这可能与 irq affinity 有关,但不确定。我也考虑过禁用 irqbalance,但不确定这是否会产生任何影响。
有什么建议么?
更新 2
NIC 驱动程序信息,我认为我们没有这个错误。因为那是在 2009 年。
driver: ixgbe
version: 4.2.1-k
firmware-version: 0x800008ea
bus-info: 0000:08:00.1
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: no
到达 eth5/6 的数据都是多播数据。这样够了吗?设置端口镜像需要向网络工程师团队提交工单,而且需要时间。我也不确定该告诉他们要寻找什么。
如果我理解正确的话,有一种方法可以将 eth6-rxtx 队列平衡到多个 CPU 核心。我自己做了一些搜索并收集了以下信息,希望对您有用。
ethtool -x
eth5
和eth6
RX flow hash indirection table for eth5 with 20 RX ring(s):
0: 0 1 2 3 4 5 6 7
8: 8 9 10 11 12 13 14 15
16: 0 1 2 3 4 5 6 7
24: 8 9 10 11 12 13 14 15
32: 0 1 2 3 4 5 6 7
40: 8 9 10 11 12 13 14 15
48: 0 1 2 3 4 5 6 7
56: 8 9 10 11 12 13 14 15
64: 0 1 2 3 4 5 6 7
72: 8 9 10 11 12 13 14 15
80: 0 1 2 3 4 5 6 7
88: 8 9 10 11 12 13 14 15
96: 0 1 2 3 4 5 6 7
104: 8 9 10 11 12 13 14 15
112: 0 1 2 3 4 5 6 7
120: 8 9 10 11 12 13 14 15
RSS hash key:
3c:f9:4a:0e:fc:7e:cb:83:c2:2a:a4:1c:cf:59:38:1c:ca:54:38:b9:6b:e8:2b:63:6e:d2:9f:eb:fc:04:c2:86:6d:e3:54:f2:73:30:6a:65
ethtool -n eth5 rx-flow-hash udp4
和eth6
UDP over IPV4 flows use these fields for computing Hash flow key:
IP SA
IP DA
我也set_irq_affinity
同时在eth5
和eth6
sudo ./set_irq_affinity local eth5
IFACE CORE MASK -> FILE
=======================
eth5 0 1 -> /proc/irq/144/smp_affinity
eth5 1 2 -> /proc/irq/145/smp_affinity
eth5 2 4 -> /proc/irq/146/smp_affinity
eth5 3 8 -> /proc/irq/147/smp_affinity
eth5 4 10 -> /proc/irq/148/smp_affinity
eth5 10 400 -> /proc/irq/149/smp_affinity
eth5 11 800 -> /proc/irq/150/smp_affinity
eth5 12 1000 -> /proc/irq/151/smp_affinity
eth5 13 2000 -> /proc/irq/152/smp_affinity
eth5 14 4000 -> /proc/irq/153/smp_affinity
eth5 0 1 -> /proc/irq/154/smp_affinity
eth5 1 2 -> /proc/irq/155/smp_affinity
eth5 2 4 -> /proc/irq/156/smp_affinity
eth5 3 8 -> /proc/irq/157/smp_affinity
eth5 4 10 -> /proc/irq/158/smp_affinity
eth5 10 400 -> /proc/irq/159/smp_affinity
eth5 11 800 -> /proc/irq/160/smp_affinity
eth5 12 1000 -> /proc/irq/161/smp_affinity
eth5 13 2000 -> /proc/irq/162/smp_affinity
eth5 14 4000 -> /proc/irq/163/smp_affinity
sudo ./set_irq_affinity local eth6
IFACE CORE MASK -> FILE
=======================
eth6 5 20 -> /proc/irq/165/smp_affinity
eth6 6 40 -> /proc/irq/166/smp_affinity
eth6 7 80 -> /proc/irq/167/smp_affinity
eth6 8 100 -> /proc/irq/168/smp_affinity
eth6 9 200 -> /proc/irq/169/smp_affinity
eth6 15 8000 -> /proc/irq/170/smp_affinity
eth6 16 10000 -> /proc/irq/171/smp_affinity
eth6 17 20000 -> /proc/irq/172/smp_affinity
eth6 18 40000 -> /proc/irq/173/smp_affinity
eth6 19 80000 -> /proc/irq/174/smp_affinity
eth6 5 20 -> /proc/irq/175/smp_affinity
eth6 6 40 -> /proc/irq/176/smp_affinity
eth6 7 80 -> /proc/irq/177/smp_affinity
eth6 8 100 -> /proc/irq/178/smp_affinity
eth6 9 200 -> /proc/irq/179/smp_affinity
eth6 15 8000 -> /proc/irq/180/smp_affinity
eth6 16 10000 -> /proc/irq/181/smp_affinity
eth6 17 20000 -> /proc/irq/182/smp_affinity
eth6 18 40000 -> /proc/irq/183/smp_affinity
eth6 19 80000 -> /proc/irq/184/smp_affinity
更新 3
我进行了修改upd4
rx-flow-hash
以包含源端口和目标端口但没有任何区别。
ethtool -n eth5 rx-flow-hash udp4
UDP over IPV4 flows use these fields for computing Hash flow key:
IP SA
IP DA
L4 bytes 0 & 1 [TCP/UDP src port]
L4 bytes 2 & 3 [TCP/UDP dst port]
禁用irqbalance
并手动更新/proc/irq/171/smp_affinity_list
以包含所有 10 个“本地”CPU 核心。
cat /proc/irq/171smp_affinity_list
5-9,15-19
这是grep 171: /proc/interrupts
我进行上述更改之后的结果(将 src 和 dst 端口添加到udp4
rx-flow-hash
并添加5-9,15-19
到/proc/irq/171/smp_affinity_list
),我们先将其称为之前。
这是grep 171: from /proc/interrupts
今天早上的事,以后再说吧。
Before 171: 0 0 0 0 0 16840 390 155 17725587 7505131 0 0 0 0 0 1282081848 184961789 21430 583751571 266997575 PCI-MSI-edge eth6-TxRx-6
After 171: 0 0 0 0 0 16840 390 155 17725587 7505131 0 0 0 0 0 1282085923 184961789 21430 583751571 267026844 PCI-MSI-edge eth6-TxRx-6
从上面可以看出,irq
171 仅由 CPU 19 处理。如果irqbalance
运行的是不同的 CPU,则会处理irq
171,由于某种原因,irq
171 似乎无法平衡到多个 CPU。
以下是数据包丢失更新
Wed Jun 5 01:39:41 EDT 2019
ethtool -S eth6 | grep -E "rx_missed|no_buff|no_dma"
rx_no_buffer_count: 0
rx_missed_errors: 2578857
rx_no_dma_resources: 3456533
Thu Jun 6 05:43:34 EDT 2019
njia@c4z-ut-rttp-b19 $ sudo ethtool -S eth6 | grep -E "rx_missed|no_buff|no_dma"
rx_no_buffer_count: 0
rx_missed_errors: 2578857
rx_no_dma_resources: 3950904
时间在这里并不重要,因为多播数据在每天下午 16:00 之后停止。
我在 Red Hat 网站上找到了这篇文章多个进程订阅同一多播组时发生数据包丢失。
我们的开发人员还提到,如果我们只运行一个应用程序实例,则掉线次数会大大减少。通常有 8 个。
增至net.core.rmem_default
4Mb
16Mb
sysctl -w net.core.rmem_default=16777216
net.core.rmem_default = 16777216
这是当前Udp
堆栈状态,明天将再次检查。
Fri Jun 7 00:40:10 EDT 2019
netstat -s | grep -A 4 Udp:
Udp:
90579753493 packets received
1052 packets to unknown port received.
1264898431 packet receive errors
1295021855 packets sent
答案1
- 检查驱动程序版本。错误
rx_no_dma_resources
当 已满时,正确计算rx buffer
。因此,请检查环形缓冲区的长度(ethtool -g <iface>
)并增加它(ethtool -G <iface> rx <size> tx <size>
,但这会导致数据包处理出现短暂中断)。
笔记:问题更新后,您知道没有错误,但我认为应该按重要性顺序解决问题。因此,让我们先解决有missing
错误的问题,然后再尝试解决rx_no_dma_resources
错误。
这
rx_missed_errors
意味着系统没有足够的 CPU 资源来处理传入的数据包。在大多数情况下,当应该执行 irq 处理程序的 CPU 核心处于负载下时,就会发生这种情况。检查命令的输出cat /proc/interrupts
。调查 NIC irq 计数器在 CPU 核心之间的分布情况。禁用irqbalance
并使用set_irq_affinity
脚本将 irq 处理程序绑定到核心。如果您的系统有多个 NUMA 域,您应该使用此脚本的local
或选项。remote
检查命令的输出
perf top
来调查是什么原因导致网络数据包处理时的 CPU 负载。
更新 1
如您在 中看到的/proc/interrupts
,一些 CPU 核心(15、18、19)处理来自eth6-TxRx-6
队列 irq 处理程序的中断比其他核心多得多(数百倍)。检查这些 CPU 核心的负载。很可能,它们经常处于过载状态。
因此,除了不正确的 CPU 亲和性和 之外irqbalance
,您还有其他问题。您应该调查通过eth6
NIC 队列 6 的主要流量类型。使用交换机端口镜像和 wireshark(从 开始Statistics - Protocol Hierarchy
)。之后,您可以使用 调整 RSS 哈希以ethtool
在多个 NIC 队列之间共享此流量。这将避免某些核心过载。
关于 NUMA 的一些说明
您询问了有关脚本的详细信息local
和remote
选项set_irq_affinity
。为了回答这个问题,我绘制了双插槽系统的简化图。
现代 CPU 具有集成内存控制器和 PCI-express 控制器。在多插槽系统中,存在一个处理器间链路,用于在处理器之间进行数据交换。每个处理器都可以访问所有内存。但是,如果一个处理器使用由另一个处理器的内存控制器管理的内存区域中的数据,则需要向该远程内存控制器请求开销,并需要对处理器间链路上的数据传输进行惩罚。
PCI-Express 设备和系统之间的数据传输通过 DMA(直接内存访问)实现,这使得外围设备无需向 CPU 发出明确请求即可将数据读取/写入 RAM。显然,这是非常具体的实现,但它也继承了相同的内存访问限制。
那么,irq affinity 是如何参与其中的呢?大致来说,当 PCI-Express NIC 从外部接收到数据时,它会使用 DMA 将该数据存储在系统 RAM 中,并生成中断以通知系统。如果中断处理程序将在另一个 CPU 上执行,而不是在本地执行,会发生什么情况?当然,中断处理程序需要接收到的数据来处理它。并且将获得远程内存的所有开销和惩罚。在最坏的情况下,它可能导致处理器间链路过载。
因此,如您所见,正确设置 NUMA 系统的 irq 亲和性非常重要。该set_irq_affinity
脚本会自动将 NIC 队列 irq 处理程序绑定到 CPU 核心。在最佳情况下,您将在 中看到非零计数器的“阶梯” /proc/interrupts
。显然,irqbalance
试图玩自己的游戏并完全消除此 irq 亲和性带来的好处。
更新 2
那么,我们目前掌握的信息是:
eth6-TxRx-6
有大量的多播流量,由中断处理程序处理。UDP4
:ip source address
和的 RSS 哈希ip destination address
。- 运行后,
set_irq_affinity
此队列的处理程序绑定到第 16 个核心。
您现在可以做什么:
监控统计数据和核心负载,特别是第 16 个核心。是否还存在过载和缺失错误?
此多播流量是唯一一个流还是多个流?如果存在多个流,您可以使用 调整 的哈希值
udp4
。ethtool
如果 NIC 不仅使用 IP 地址进行哈希值计算,还使用 和端口号,则它可能能够在多个接收队列之间共享处理,从而在多个 CPU 核心之间共享处理。如果这是唯一的一个流,那么您可以尝试将更多 CPU 核心绑定到相应的 irq 处理程序。
更新 3
因此,您同时遇到了几个问题。
- 在
netstat
输出中您有:
1264898431 数据包接收错误
但这些错误与丢失错误无关。当系统没有足够的 CPU 资源来处理中断时,数据包将在执行任何协议处理程序之前丢失。如果 UDP 套接字缓冲区的内存不足,您将在命令的输出中看到相应的错误nstat -az UdpRcvbufErrors
。监视它并使用 sysctl 变量增加内存限制。您还可以使用工具监视套接字的接收队列ss
。这也很有帮助。
调查哪些进程消耗了 CPU 时间。之后,您可以使用
perf record
或分析工作负载perf top
。它真的softirq
使单核过载吗?这个内核进程维护着很多东西,因此perf top
调查到底是什么消耗了最多的 CPU 时间会很有帮助。如果您只有一个多播组,则此流将只执行单个 irq,因为 n-tuple-hash 将始终相同。我不知道这种情况有什么解决方法。唯一的方法是使用更快的处理器。您还可以检查
i7z
工具的结果以监视 CPU 的睡眠状态。我不知道您的应用程序架构细节,但当运行多个实例时,您可能也遇到了多播 UDP 数据报丢失的问题。也许这也与应用程序实例与 CPU 核心的错误绑定有关。尝试将应用程序进程绑定到 CPU 核心。
附言当您提供有关上述步骤的结果的信息时,我会扩展答案。