在运行 RHEL 6.10 的 HP ProLiant DL360 G9 上丢包

Ask*_*arn 4 linux performance-tuning linux-networking

我们有一台运行 RHEL 6.10 和 2 X 的 HP ProLiant DL360 G9 Intel 82599ES 10-Gigabit SFI/SFP+。HP 产品名称是HP Ethernet 10Gb 2-port 560SFP+ Adapter

eth5eth6显示大量数据包丢失 ( rx_missed_errors) 我禁用了 NIC 级别的流量控制,然后rx_missed_errors停止增加但rx_no_dma_resources开始每天增加。

  • 它们都是独立的接口,不是绑定的一部分。
  • Eth5 和 eth6 在不同的卡上
  • 两个卡都安装到 PCIe 3.0 X16 插槽
  • irqbalance 正在服务器上运行

更新 1

环参数eth5eth6处于最大值相同,已经。

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
Run Code Online (Sandbox Code Playgroud)

我注意到以下为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

Run Code Online (Sandbox Code Playgroud)

所以看起来 CPU/Core 15/18/19 承受着处理 eth6 上的流量的压力

基本上我不知道下一步该往哪里看,我猜这可能与 irq 亲和力有关,但不确定。我也想禁用 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
Run Code Online (Sandbox Code Playgroud)

到达 eth5/6 的数据都是多播数据。够了,设置端口镜像需要网络工程师团队的票并且需要时间。我也不知道该告诉他们要寻找什么。

如果我正确理解您的评论,有一种方法可以将 eth6-rxtx 队列平衡到多个 CPU 内核。我自己做了一些搜索并收集了以下信息,希望对您有用。

ethtool -x eth5eth6

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
Run Code Online (Sandbox Code Playgroud)

ethtool -n eth5 rx-flow-hash udp4eth6

UDP over IPV4 flows use these fields for computing Hash flow key:
IP SA
IP DA
Run Code Online (Sandbox Code Playgroud)

我也运行set_irq_affinity在两个eth5eth6

sudo ./set_irq_affinity local eth5
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
sudo ./set_irq_affinity local eth6
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

更新 3

我修改upd4 rx-flow-hash为包含源端口和目标端口,但没有任何区别。

ethtool -n eth5 rx-flow-hash udp4
Run Code Online (Sandbox Code Playgroud)
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]
Run Code Online (Sandbox Code Playgroud)

禁用irqbalance并手动更新/proc/irq/171/smp_affinity_list以包含所有 10 个“本地”CPU 内核。

cat /proc/irq/171smp_affinity_list
Run Code Online (Sandbox Code Playgroud)
5-9,15-19
Run Code Online (Sandbox Code Playgroud)

这是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

Run Code Online (Sandbox Code Playgroud)

从上面可以看出,irq171 只由 CPU 19 处理。如果irqbalance正在运行不同的 CPU 将处理irq171,似乎由于某种原因,irq171 不能平衡到多个 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

Run Code Online (Sandbox Code Playgroud)

时间在这里无关紧要,因为组播数据在每天下午 16:00 后停止。

我在 Red Hat 站点上发现了这篇文章,当多个进程订阅同一个多播组时会丢失数据包

我们的开发人员还提到,如果我们的应用程序只有一个实例运行,滴数会显着减少。通常有8个。

增加net.core.rmem_default4Mb16Mb

sysctl -w net.core.rmem_default=16777216
net.core.rmem_default = 16777216
Run Code Online (Sandbox Code Playgroud)

这是当前的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
Run Code Online (Sandbox Code Playgroud)

Ant*_*lov 6

  1. 检查驱动程序版本。有错误与正确的会计rx_no_dma_resources,当rx buffer已满。所以检查环形缓冲区的长度(ethtool -g <iface>)并增加它(ethtool -G <iface> rx <size> tx <size>,但它会导致数据包处理中的短时间中断)。

注意:更新问题后,您已经知道没有错误,但是,我认为应该按重要性顺序解决问题。因此,让我们解决missing错误问题,然后再尝试解决rx_no_dma_resources错误。

  1. rx_missed_errors意味着系统没有足够的 CPU 资源来处理传入的数据包。在大多数情况下,它发生在应该执行 irq 处理程序的 cpu 核心处于负载下时。检查cat /proc/interrupts命令的输出。调查 NIC irq 计数器如何在 CPU 内核之间分配。禁用irqbalance并使用set_irq_affinity脚本将 irq 处理程序绑定到内核。如果您的系统有多个 NUMA 域,您应该使用此脚本的localremote选项。

  2. 检查perf top命令的输出以调查导致网络数据包处理时 cpu 负载的原因。

更新 1

正如您在 中看到的/proc/interrupts,某些 CPU 内核(15、18、19)处理的来自eth6-TxRx-6队列 irq 处理程序的中断比其他内核多得多(数百次)。检查这些 CPU 内核的负载。很可能,他们经常处于超负荷状态。

因此,除了不正确的 CPU 关联性和 之外irqbalance,您还有其他问题。您应该调查通过eth6NIC队列 6 的主要流量类型。使用交换机端口镜像和wireshark(从 开始Statistics - Protocol Hierarchy)。在此之后,您可以调整 RSS 散列以ethtool在多个 NIC 队列之间共享此流量。它将避免某些内核的过载。

关于 NUMA 的一些说明

您已经询问了脚本的详细信息localremote选项set_irq_affinity。为了回答这个问题,我画了一个双插槽系统的简化图。

双插座系统图

现代 CPU 具有集成的内存控制器和 PCI-express 控制器。在多插槽系统的情况下,有一个处理器间链接来提供处理器之间的数据交换。每个处理器都可以访问所有内存。但是,如果处理器处理由另一个处理器的内存控制器管理的内存区域中的数据,则需要向该远程内存控制器请求的开销以及处理器间链路上的数据传输的惩罚。

PCI-Express 设备和系统之间的数据传输是通过 DMA(直接内存访问)实现的,外围设备可以在不向 CPU 明确请求的情况下将数据读/写到 RAM 中。显然,它是特定于实现的,但它也继承了相同的内存访问限制。

那么,irq 亲和性如何参与其中呢?粗略地说,当 PCI-Express 网卡从外部接收到数据时,它会将该数据通过 DMA 存储在系统 RAM 中,并产生中断通知系统。如果中断处理程序将在另一个 CPU 上执行,而不是在本地执行,会发生什么?自然,中断处理程序需要接收到的数据来处理它。并且将获得远程内存的所有开销和惩罚。在最坏的情况下,它会导致处理器间链接过载。

因此,如您所见,为 NUMA 系统正确设置 irq 关联非常重要。该set_irq_affinity脚本自动将 NIC 队列 irq 处理程序绑定到 CPU 内核。在最好的情况下,您会在/proc/interrupts. 显然,irqbalance尝试在自己的游戏中玩并完全扼杀了这种 irq 亲和力的好处。

更新 2

那么,我们目前掌握的信息是:

  • 有很多多播流量,由eth6-TxRx-6中断处理程序处理。
  • 的 RSS 哈希UDP4ip source addressip destination address
  • set_irq_affinity此队列的处理程序运行后绑定到第 16 个核心。

你现在可以做什么:

  • 监控统计数据和核心负载,尤其是第 16 个核心。是否仍然存在重载和丢失错误?

  • 这个多播流量是唯一的一个流还是几个流?如果有多个流,您可以调整udp4with的散列ethtool。如果 NIC 不仅将 ip 地址用于散列,而且还使用端口号,则它可能能够在多个接收队列之间共享处理,因此,在多个 cpu 内核之间共享。如果这是唯一的一个流程,那么您可以尝试绑定到对应的 irq 处理程序更多的 cpu 内核。

更新 3

所以,你同时有几个问题。

  1. netstat输出中,您有:

1264898431 数据包接收错误

但这些错误与遗漏的错误无关。当系统没有足够的 CPU 资源来处理 irq 时,数据包将在任何协议处理程序执行之前丢失。如果 UDP 套接字缓冲区的内存不足,您将在nstat -az UdpRcvbufErrors命令的输出中看到相应的错误。监视它并使用 sysctl 变量增加内存限制。您还可以使用ss工具监视套接字的接收队列。它也很有帮助。

  1. 调查一下,是什么进程消耗了cpu时间。在此之后,您可以使用perf record或来分析工作负载perf top。真的是softirq单核超载吗?这个内核进程维护了很多东西,所以perf top将有助于调查究竟是什么消耗了大部分 cpu 时间。

  2. 如果您只有一个多播组,则此流只会执行单个 irq,因为 n-tuple-hash 将始终相同。我不知道这种情况下的任何解决方法。唯一的方法是使用更快的处理器。您也可以检查i7z工具的结果来监控 CPU 的睡眠状态。

  3. 我不知道您的应用程序架构细节,但是当运行多个实例时,您可能也会遇到多播 udp 数据报丢失的问题。也许它也与应用程序实例与 CPU 内核的错误绑定有关。尝试将应用程序进程绑定到 CPU 内核。

PS当您提供有关上述步骤结果的信息时,我将扩展答案。