在Linux的网络调优方面,如果你发现网络流量上不去,那么有一个方面需要去查一下:网卡处理网络请求的中断是否被绑定到单个CPU(或者说跟处理其它中断的是同一个CPU)。

先说一下背景

网卡与操作系统的交互一般有两种方式,

  • 一种是中断(IRQ,网卡在收到了网络信号之后,主动发送中断到CPU,而CPU将会立即停下手边的活以便对这个中断信号进行分析),
  • 另一种叫DMA(Direct Memory Access, 也就是允许硬件在无CPU干预的情况下将数据缓存在指定的内存空间内,在CPU合适的时候才处理)

——记得在10多年前开始玩电脑的时候就知道DMA是效率比较高的方式了。但是,这么多年过去了,在网卡方面,大部分还是在用IRQ方式(据说DMA技术仅仅被应用在少数高端网卡上; 另一个说法是:DMA方式会使外部设备的控制器独占PCI总线,从而CPU无法与外部设备进行交互,这对通用型操作系统Linux来说,是很难接收的,所以DMA方式在Linux内核里使用得很少)。

但是(再来一个但是),在现在的对称多核处理器(SMP)上,一块网卡的IRQ还是只有一个CPU来响应,其它CPU无法参与,如果这个CPU还要忙其它的中断(其它网卡或者其它使用中断的外设(比如磁盘)),那么就会形成瓶颈。

问题判定

网上不少讲这个问题的文章都是直接让查询IRQ跟CPU的绑定情况,甚至直接修改。但我们应该先判断我们的系统是不是受这个问题影响,然后再来看怎么解决。

首先,让你的网络跑满(比如对于MySQL/MongoDB服务,可以通过客户端发起密集的读操作; 或者执行一个i大文件传送任务)

第一个要查明的是:是不是某个CPU在一直忙着处理IRQ?

这个问题我们可以从 mpstat -P ALL 1 的输出中查明:里面的 %irq 一列即说明了CPU忙于处理中断的时间占比

18:20:33     CPU   %user   %nice    %sys %iowait    %irq   %soft  %steal   %idle    intr/s
18:20:33 all 0,23 0,00 0,08 0,11 6,41 0,02 0,00 93,16 2149,29
18:20:33 0 0,25 0,00 0,12 0,07 0,01 0,05 0,00 99,49 127,08
18:20:33 1 0,14 0,00 0,03 0,04 0,00 0,00 0,00 99,78 0,00
18:20:33 2 0,23 0,00 0,02 0,03 0,00 0,00 0,00 99,72 0,02
18:20:33 3 0,28 0,00 0,15 0,28 25,63 0,03 0,00 73,64 2022,19

上面的例子中,第四个CPU有25.63%时间在忙于处理中断(这个数值还不算高,如果高达80%(而同时其它CPU这个数值很低)以上就说明有问题了),后面那个 intr/s 也说明了CPU每秒处理的中断数(从上面的数据也可以看出,其它几个CPU都不怎么处理中断)。

然后我们就要接着查另外一个问题:这个忙于处理中断的CPU都在处理哪个(些)中断?

cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 245 0 0 7134094 IO-APIC-edge timer
8: 0 0 49 0 IO-APIC-edge rtc
9: 0 0 0 0 IO-APIC-level acpi
66: 67 0 0 0 IO-APIC-level ehci_hcd:usb2
74: 902214 0 0 0 PCI-MSI eth0
169: 0 0 79 0 IO-APIC-level ehci_hcd:usb1
177: 0 0 0 7170885 IO-APIC-level ata_piix, b4xxp
185: 0 0 0 59375 IO-APIC-level ata_piix
NMI: 0 0 0 0
LOC: 7104234 7104239 7104243 7104218
ERR: 0
MIS: 0

这里记录的是自启动以来,每个CPU处理各类中断的数量(第一列是中断号,最后一列是对应的设备名)[详细说明: E.2.10 /proc/interrupts - Deployment Guide - RedHat Enterprise Linux 6 ),从上面可以看到: eth0 所出发的中断全部都是 CPU0 在处理,而CPU0所处理的中断请求中,主要是eth0和LOC中断。(有时我们会看到几个CPU对同一个中断类型所处理的的请求数相差无几(比如上面的LOC一行),这并不一定是说多个CPU会轮流处理同一个中断,而是因为这里记录的是“自启动以来”的统计,中间可能因为irq balancer重新分配过处理中断的CPU——当然,也可能是谁手工调节过)。

解决问题

首先说明几点:

  1. 首先应该根据上面的诊断方法查明当前系统是不是受这个原因影响,如果不是,那么就没有必要往下看了;
  2. 现在的多数Linux系统中已经有了IRQ Balance这个服务(服务程序一般是 /usr/sbin/irqbalance),它可以自动调节分配各个中断与CPU的绑定关系,以避免所有中断的处理都集中在少数几个CPU上;
  3. 在某些情况下,这个IRQ Balance反而会导致问题,会出现 irqbalance 这个进程反而自身占用了较高的CPU(当然也就影响了业务系统的性能)[参考: mongodb性能问题及原理分析 ]

下面来说手工将中断限定到少数几个CPU的方法。

首先当然要查明,该网卡的中断当前是否已经限定到某些CPU了?具体是哪些CPU?

根据上面 /proc/interrupts 的内容我们可以看到 eth0 的中断号是74,然后我们来看看该中断号的CPU绑定情况(或者说叫亲和性 affinity)

$ sudo cat /proc/irq/74/smp_affinity
ffffff

这个输出是一个16进制的数值,0xffffff = ‘0b111111111111111111111111’,这就意味着这里有24个CPU,所有位都为1表示所有CPU都可以被该中断干扰。

另一个例子:

$ sudo cat /proc/irq/67/smp_affinity
00000001

这个例子说明,只有CPU0处理编号为67的中断。

修改配置的方法

我们可以用 echo 2 > /proc/irq/74/smp_affinity 的方法来修改这个设置(设置为2表示将该中断绑定到CPU1上,0x2 = 0b10,而第一个CPU为CPU0)

参考

[Linux 性能调优] 网卡中断与CPU的绑定问题的更多相关文章

  1. linux性能调优概述

    - 什么是性能调优?(what) - 为什么需要性能调优?(why) - 什么时候需要性能调优?(when) - 什么地方需要性能调优?(where) - 什么人来进行性能调优?(who) - 怎么样 ...

  2. <Linux性能调优指南>主要思路流程

    网上IBM很早放出的一本免费电子书, 十来年了,参考意义还是很大. 国内有翻译成中文在线阅读的版本. 见如下两个URL Linux Performance and Tuning Guidelines ...

  3. 转载linux性能调优工具

    Linux 大牛,Netflix 高级性能架构师 Brendan Gregg 更新 Linux 性能调优工具,各种资源应有尽有,大量干货,强烈建议收藏.

  4. linux 性能调优工具参考 (linux performance tools)

    之前发现几张图对于linux使用者有着较强的参考意义,下面对其进行简单备忘: # linux 静态信息查看工具 # linux 性能测试工具 benchmark # linux 性能观测工具 # li ...

  5. 【Linux性能调优一】观大局:系统平均负载load average

    要测试linux系统性能及调优,首先要从全局检查linux的平均负载 1.什么是平均负载 load average 系统平均负载,平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数, ...

  6. Nginx + Linux 性能调优

    Nginx以高性能负载均衡.缓存和web服务器出名,支撑着世界上繁忙网站中的40%.大多数使用场景下,Nginx和Linux系统的默认配置表现较好,但是仍有必要做一些调优以期达到最佳性能. 这篇文章讨 ...

  7. linux性能调优

    1-1.0  关于ulimit linux对每个用户,系统限制其最大进程数.为提高性能,可根据设备资源情况,设置各linux用户最大进程数. [Qrui@root ~]#ulimit -a 用来显示当 ...

  8. [Linux性能调优] 磁盘I/O队列调度策略

    这两天的一个小任务是MongoDB服务器的调优,恰好这段时间对Linux的各种性能诊断.调优感兴趣,就顺着这个任务多翻了些书和文章. 新学到的一个东西是 Linux磁盘的I/O队列调度策略,至少MyS ...

  9. Linux性能调优之gprof和oprofile

    为了更好的优化程序性能,我们必须找到性能瓶颈点,“好钢用在刀刃上”才能取 得好的效果,否则可能白做工作. 为了找到关键路径,我们可以使用profilng技术,在linux平台上,我们可以使用gprof ...

随机推荐

  1. SQL的多种JOIN

  2. [P1879][USACO06NOV]玉米田Corn Fields (状态压缩)

    最近题目都有状态压缩,我是蒟蒻,并不会状态压缩 然后我决定学了! 然后发现我学不来. OI-WIKI上的界面给我推荐了这道题https://oi-wiki.org/dp/state/ 状态压缩入门题, ...

  3. Python基础-列表、元祖、字典、字符串

    列表和分组 序列概览: 数据结构是通过某种方式组织在一起的数据元素的集合.这些元素可以是数字.字符,甚至可以是其他数据结构. 在python中,最基本的数据结构是序列(sequence). 序列中的每 ...

  4. nullptr/NULL

    NULL vs nullptr 在过去,我们如果要表示一个指针为空,我们条件反射肯定会这么写: int *p = NULL; 然而啊,有没有想过这是有问题的,比如下面的这段代码: #include & ...

  5. H3C505

    H3C505 1.立方体案例 2.3D变换 1)景深透视 prospective:xx px; 设置观察元素的距离,数值小时,在元素内进行观察 prospective-origin: xpx,xpx ...

  6. Spring(2)—IOC

    一.Spring IOC是什么 1.简述 Spring是一个开源框架 Spring为简化企业级应用开发而生,使用Spring可以使简单的JavaBean实现以前只有EJB才能实现的功能 Spring是 ...

  7. Java全栈程序员之08:MAVEN+JAVA配置

    从Spring3.0开始,Spring支持以Java配置的方式来代替XML配置.这一点说起来其实有点可笑,XML配置的方式最初被创建出来就是为了让配置与程序员无关.可是最终我们发现,绝大多数的那些配置 ...

  8. Android:如何生成自己的keystore(zz)

    keystore不设置的话默认使用的是C:\Users\Fly\.Android下面的debug.keystore,每台电脑的都不一样,所以导致了无法安装的情况. 如何生成自己的keystore呢?这 ...

  9. python 2 字典的基本使用

    dicVisit={} if not dicVisit.has_key(visitKey):#不存在 diaSet = set() diaSet.add(diagnoseContent) dicVis ...

  10. linux clamav 免费查毒工具

    linux下需要杀毒工具吗?我一直认为是不要的,基于linux的病毒很少,linux 安全防护也做的很好,一般很难功破.我想那些黑客们更喜欢,写windows下的病毒,用的人多啊,传播也容易.下面的操 ...