数据和云
小米运维

和小米一起聊技术,一起改变生活

 

 

什么是中断

CPU 工作的模式有两种,一种是中断,由各种设备发起;一种是轮询,由 CPU 主动发起。

我们先解释中断。

中断又分为两种:一种硬中断;一种软中断。硬中断是由硬件产生的,比如,像磁盘,网卡,键盘;软中断是由当前正在运行的进程所产生的。

中断,是一种由硬件产生的电信号直接发送到中断控制器上,然后由中断控制器向 CPU 发送信号,CPU 检测到该信号后,会中断当前的工作转而去处理中断。然后,处理器会通知内核已经产生中断,这样内核就会对这个中断进行适当的处理。

栗子 1:

当我们敲击键盘时,键盘就会产生一个中断请求通知到 CPU,CPU 会中断当前正在运行的任务并保存当前状态到堆栈中,转而处理键盘发出来的请求。

栗子 2:

当网卡收到数据包时会产生中断请求通知到 CPU,CPU 会中断当前正在运行的任务,然后通知内核有新数据包,内核调用中断处理程序进行响应,把数据包从网卡缓存及时拷贝到内存,否则会因为缓存溢出被丢弃。剩下的处理和操作数据包的工作就会交给软中断。

 

通过上面的例子我们应该能理解中断的含义,那 CPU 另一种工作模式,轮询怎么理解呢? 

简单理解就是让 CPU 定时对硬件状态进行查询然后做相应处理。

两种工作方式相比较,哪一种更好? 举个栗子:

中断就好比工作中收到微信消息,当有消息提示,我们停止手中的工作查看消息就是中断。轮询就是每隔几分钟去检查一下微信有没有新消息 。如果想要及时关注并处理消息,中断的方式是不是比轮询 (CPU 主动) 更有效一些呢。

 

什么是多队列网卡

上面我们已经理解了中断,是硬件主动发送信号给 CPU。 可是当网卡不断的接收数据包,就会产生很多中断,CPU 又如何能满足需求呢? 

答案是当然有办法,就是我们要说的多队列网卡技术。原理如下:

RSS(Receive Side Scaling)是网卡的硬件特性,实现了多队列。通过多队列网卡驱动加载,获取网卡型号,得到网卡的硬件 queue 的数量,并结合 CPU 核的数量,最终通过 Sum=Min(网卡 queue,CPU core)得出所要激活的网卡 queue 数量。

然后将各个 queue 中断分布到 CPU 多个核上,实现负载均衡,避免了单个核被占用到 100% 而其他核还处于空闲的情况。同一数据流会始终在同一 cpu 上,避免 tcp 的顺序性和 cpu 的并行性的冲突。基于流的负载均衡,解决了顺序协议和 cpu 并行的冲突以及 cache 热度问题。

 

多队列需要网卡硬件的支持。如果服务器的网卡支持 RSS,会在系统中看到网卡对应多个发送和接收队列:

再也不用担心无法将中断绑定到多队列网了_Java

在使用不支持 RSS 的网卡时,为了充分利用多核 cpu,centos6.1 开始提供了 RPS(Receive Packet Steering)和 RFS(Receive Flow Steering)。在这里我们不做论述。

 

为什么将中断绑定到多队列网卡

对于高流量 Web 服务器来说,把不同的网卡队列均衡的绑定到不同的 CPU 上,相当于将网卡数据包产生的中断负载均衡到不同的 CPU 上。避免单核处理中断,提高多个 CPU 整体处理中断的能力。

对于数据库服务器来说,把网卡绑定到另一个 CPU 将会提高数据库的响应时间、优化性能。

所以,平衡硬件中断有助于提高系统的整体吞吐能力和性能。

 

如何知道中断来自哪个设备

上面说到每个硬件设备都有中断,那如何区分哪个中断来自哪个硬件来呢?  

答案:IRQ (Interrupt Request)。系统上的每个硬件设备都会被分配一个 IRQ 号,通过这个唯一的 IRQ 号就能区是来自哪个硬件了。

如下图:

再也不用担心无法将中断绑定到多队列网了_Java_02

第 1 列:IRQ 号 。 

第 2~9 列表示相应的 CPU 被中断的次数。 

最后一列表示中断的设备

这里说明一下,IRQ 号决定了需要被 CPU 处理的优先级,IRQ 号越小意味着被优先执行的级别越高。如下图,timer 时钟 IRQ 号为 0,i8042 键盘 IRQ 号为 1。

如果 CPU 同时接收了来自键盘和系统时钟的中断,那么 CPU 首先会服务于系统时钟,因为他的 IRQ 号是 0。

 

网卡中断绑定

 

1,在动手之前我们需要先停掉 IRQ 自动调节的服务进程,这样才能手动绑定 IRQ 到不同 CPU,否则自己手动绑定做的更改将会被自动调节进程给覆盖掉。

再也不用担心无法将中断绑定到多队列网了_Java_03

 

2,查看网卡的 IRQ 号。从上面大图可见,网卡多队列 IRQ 号 44~51.

/proc/interrupts:

该文件存放了每个 I/O 设备的对应中断号、每个 CPU 的中断数、中断类型。

/proc/irq/[irq_num]/smp_affinity:

该文件存放的是 CPU 位掩码(十六进制)。修改该文件中的值可以改变 CPU 和某中断的亲和性。

/proc/irq/[irq_num]/smp_affinity_list:

该文件存放的是 CPU 列表(十进制)。注意,CPU 核心个数用表示编号从 0 开始,如 cpu0,cpu1 等。

 

3,将 CPU 核修改到对应的中断文件中。如果是绑定多个 cpu 则用逗号隔开,如果是绑定连续 CPU,则用 - 符号。

再也不用担心无法将中断绑定到多队列网了_Java_04

 

中断绑定后效果:

如果没有进行中断绑定,网卡流量会集中在 CPU 一个核上。中断绑定后会分布在 CPU 多个核心。

再也不用担心无法将中断绑定到多队列网了_Java_05

 

 

转载自:小米运维。

投稿:有投稿意向技术人请在公众号对话框留言。

转载:意向文章下方留言。