CPU0 被 eth1 中断淹没

CPU0 被 eth1 中断淹没

我有一个 Ubuntu VM,在基于 Ubuntu 的 Xen XCP 中运行。它托管一个基于 FCGI 的自定义 HTTP 服务nginx

负载下ab 第一个 CPU 核心已饱和,其余核心负载不足。

/proc/interrupts看到CPU0 提供的中断比任何其他核心都要多一个数量级。其中大多数来自eth1

我可以做些什么来提高此虚拟机的性能?有没有办法更均匀地平衡中断?


血腥细节:

$ uname -a
Linux MYHOST 2.6.38-15-virtual #59-Ubuntu SMP 2012 年 4 月 27 日星期五 16:40:18 UTC i686 i686 i386 GNU/Linux

$ lsb_release-a
无可用的 LSB 模块。
分销商 ID:Ubuntu
描述:Ubuntu 11.04
发行:11.04
代号:natty

$ cat /proc/interrupts
           CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7       
283:113720624 0 0 0 0 0 0 0 xen-dyn-事件 eth1
284:1 0 0 0 0 0 0 0 xen-dyn-事件 eth0
285:2254 0 0 3873799 0 0 0 0 xen-dyn-事件 blkif
286:23 0 0 0 0 0 0 0 xen-dyn-事件 hvc_console
287:492 42 0 0 0 0 0 295324 xen-dyn-事件 xenbus
288:0 0 0 0 0 0 0 222294 xen-percpu-ipi callfuncsingle7
289:0 0 0 0 0 0 0 0 xen-percpu-virq debug7
290:0 0 0 0 0 0 0 151302 xen-percpu-ipi callfunc7
291:0 0 0 0 0 0 0 3236015 xen-percpu-ipi resched7
292:0 0 0 0 0 0 0 60064 xen-percpu-ipi spinlock7
293:0 0 0 0 0 0 0 12355510 xen-percpu-virq timer7
294:0 0 0 0 0 0 803174 0 xen-percpu-ipi callfuncsingle6
295:0 0 0 0 0 0 0 0 xen-percpu-virq 调试6
296:0 0 0 0 0 0 60027 0 xen-percpu-ipi callfunc6
297:0 0 0 0 0 0 5374762 0 xen-percpu-ipi resched6
298:0 0 0 0 0 0 64976 0 xen-percpu-ipi spinlock6
299:0 0 0 0 0 0 15294870 0 xen-percpu-virq timer6
300:0 0 0 0 0 264441 0 0 xen-percpu-ipi callfuncsingle5
301:0 0 0 0 0 0 0 0 xen-percpu-virq 调试5
302:0 0 0 0 0 79324 0 0 xen-percpu-ipi callfunc5
303:0 0 0 0 0 3468144 0 0 xen-percpu-ipi resched5
304:0 0 0 0 0 66269 0 0 xen-percpu-ipi spinlock5
305:0 0 0 0 0 12778464 0 0 xen-percpu-virq 计时器5
306:0 0 0 0 844591 0 0 0 xen-percpu-ipi callfuncsingle4
307:0 0 0 0 0 0 0 0 xen-percpu-virq 调试4
308:0 0 0 0 75293 0 0 0 xen-percpu-ipi callfunc4
309:0 0 0 0 3482146 0 0 0 xen-percpu-ipi resched4
310:0 0 0 0 79312 0 0 0 xen-percpu-ipi spinlock4
311:0 0 0 0 21642424 0 0 0 xen-percpu-virq 计时器4
312:0 0 0 449141 0 0 0 0 xen-percpu-ipi callfuncsingle3
313:0 0 0 0 0 0 0 0 xen-percpu-virq 调试3
314:0 0 0 95405 0 0 0 0 xen-percpu-ipi callfunc3
315:0 0 0 3802992 0 0 0 0 xen-percpu-ipi resched3
316:0 0 0 76607 0 0 0 0 xen-percpu-ipi spinlock3
317:0 0 0 16439729 0 0 0 0 xen-percpu-virq 计时器3
318:0 0 876383 0 0 0 0 0 xen-percpu-ipi callfuncsingle2
319:0 0 0 0 0 0 0 0 xen-percpu-virq 调试2
320:0 0 76416 0 0 0 0 0 xen-percpu-ipi callfunc2
321:0 0 3422476 0 0 0 0 0 xen-percpu-ipi resched2
322:0 0 69217 0 0 0 0 0 xen-percpu-ipi 自旋锁2
323:0 0 10247182 0 0 0 0 0 xen-percpu-virq 计时器2
324:0 393514 0 0 0 0 0 0 xen-percpu-ipi callfuncsingle1
325:0 0 0 0 0 0 0 0 xen-percpu-virq 调试1
326:0 95773 0 0 0 0 0 0 xen-percpu-ipi callfunc1
327:0 3551629 0 0 0 0 0 0 xen-percpu-ipi resched1
328:0 77823 0 0 0 0 0 0 xen-percpu-ipi 自旋锁1
329:0 13784021 0 0 0 0 0 0 xen-percpu-virq 计时器1
330:730435 0 0 0 0 0 0 0 xen-percpu-ipi callfuncsingle0
331:0 0 0 0 0 0 0 0 xen-percpu-virq debug0
332:39649 0 0 0 0 0 0 0 xen-percpu-ipi callfunc0
333:3607120 0 0 0 0 0 0 0 xen-percpu-ipi resched0
334:348740 0 0 0 0 0 0 0 xen-percpu-ipi spinlock0
335:89912004 0 0 0 0 0 0 0 xen-percpu-virq timer0
NMI:0 0 0 0 0 0 0 0 不可屏蔽中断
LOC: 0 0 0 0 0 0 0 0 本地定时器中断
SPU:0 0 0 0 0 0 0 0 虚假中断
PMI:0 0 0 0 0 0 0 0 性能监控中断
IWI: 0 0 0 0 0 0 0 0 IRQ 工作中断
RES:3607120 3551629 3422476 3802992 3482146 3468144 5374762 3236015 重新安排中断
CAL: 770084 489287 952799 544546 919884 343765 863201 373596 函数调用中断
TLB:0 0 0 0 0 0 0 0 TLB 被击落
TRM: 0 0 0 0 0 0 0 0 热事件中断
THR:0 0 0 0 0 0 0 0 阈值 APIC 中断
MCE:0 0 0 0 0 0 0 0 机器检查异常
MCP:0 0 0 0 0 0 0 0 机器检查轮询
错误:0
错误信息:0

答案1

查看/proc/irq/283目录。有一个smp_affinity_list文件显示哪些 CPU 将获得 283 中断。对于您来说,此文件可能包含“0”(也smp_affinity可能包含“1”)。

您可以将 CPU 范围写入文件smp_affinity_list

echo 0-7 | sudo tee /proc/irq/283/smp_affinity_list

或者您可以编写一个位掩码,其中每个位对应一个 CPU,以便smp_affinity

printf %x $((2**8-1)) | sudo tee /proc/irq/283/smp_affinity

然而,中断平衡众所周知,它对每个中断应具有的亲和性有自己的想法,并且可能会恢复您的更新。因此,最好完全卸载 irqbalance。或者至少停止它并禁止它在重新启动时出现。

如果即使没有 irqbalance,您在重启后仍遇到smp_affinity中断 283 异常,那么您必须在其中一个启动脚本中手动更新 CPU 亲和性。

答案2

如果您拥有正确型号的英特尔 NIC,您可以显著提高性能。

引用第一段:

多核处理器和最新的以太网适配器(包括 82575、82576、82598 和 82599)允许通过将执行流分配给各个核心来优化 TCP 转发流。默认情况下,Linux 会自动将中断分配给处理器核心。目前有两种方法可以自动分配中断,即内核 IRQ 平衡器和用户空间中的 IRQ 平衡守护进程。这两种方法都提供了可能降低 CPU 使用率但不会最大化 IP 转发率的权衡。可以通过手动将以太网适配器的队列固定到特定处理器核心来获得最佳吞吐量。

对于 IP 转发,发送/接收队列对应使用相同的处理器核心,并减少不同核心之间的任何缓存同步。这可以通过将发送和接收中断分配给特定核心来实现。从 Linux 内核 2.6.27 开始,可以在 82575、82576、82598 和 82599 上使用多个队列。此外,在扩展消息传递信号中断 (MSI-X) 中启用了多个发送队列。MSI-X 支持更多可用的中断,从而允许更精细地控制并将中断定位到特定 CPU。

看:使用英特尔® 82575/82576 或 82598/82599 以太网控制器将中断分配给处理器内核

答案3

实际上建议,特别是在处理短时间内重复的过程时,由设备队列生成的所有中断都由同一个 CPU 处理,而不是 IRQ 平衡因此,如果单个 CPU 处理下面提供的 eth1 中断*** 异常,您将看到更好的性能

上面链接的来源来自 Linux 研讨会,我建议你阅读一下SMP IRQ 亲和性因为它比这篇文章更能有效地说服你。

为什么?

回想一下,每个处理器除了能够访问主内存外,还有自己的缓存,看看这个图表触发中断时,CPU 核心必须从主内存中获取处理中断的指令,这比指令在缓存中花费的时间要长得多。一旦处理器执行了一项任务,它就会将这些指令保存在缓存中。现在假设同一个 CPU 核心几乎一直处理同一个中断,中断处理程序函数不太可能离开 CPU 核心缓存,从而提高内核性能。

或者,当IRQ平衡时,它可以将中断不断地分配给不同的CPU来处理,那么新的CPU核心很可能在缓存中没有中断处理程序函数,并且需要很长时间才能从主内存中获取适当的处理程序。

例外:如果您很少使用 eth1 中断,这意味着经过足够的时间后缓存会被执行其他任务所覆盖,这意味着您会在较长的时间间隔内间歇性地通过该接口传输数据……那么您很可能不会看到这些好处,因为它们是在您以高频率使用某个进程时产生的。

结论

如果您的中断发生非常通常只需将该中断绑定到特定 CPU 即可。此配置位于

 /proc/'IRQ number'/smp_affinity

或者

/proc/irq/'IRQ number'/smp_affinity

请参阅SMP IRQ 亲和性来自上面链接的来源的部分,它有说明。

或者

您可以通过增加 MTU 大小(巨型帧)来更改中断标志发出的频率(如果网络允许的话),或者更改为在收到大量数据包后而不是每个数据包时都发出标志,或者更改超时时间,以便在一定时间后发出中断。请谨慎使用时间选项,因为您的缓冲区大小可能在时间用完之前就已满。这可以使用ethtool这在链接源中有概述。

这个答案的长度已经接近人们不会阅读的长度,所以我就不赘述了,但根据你的情况,有很多解决方案...请查看来源:)

相关内容