过段时间在看 /proc/interrupts,是不是 90:eth0 在 CPU1 上的中断增加了(145)、在 CPU0 上的中断没变?不断打印 /proc/interrupts 就会发现 eth0 在 CPU0 上的中断数始终保持不变,而在 CPU1 上的中断数是持续增加的,这正是我们想要的结果:
# cat /proc/interrupts CPU0 CPU1 0: 922506515 0 IO-APIC-edge timer 1: 2 0 IO-APIC-edge i8042 8: 0 0 IO-APIC-edge rtc 9: 0 0 IO-APIC-level acpi 12: 4 0 IO-APIC-edge i8042 14: 8280147 0 IO-APIC-edge ide0 50: 194 0 IO-APIC-level ohci_hcd:usb2 58: 31907 0 IO-APIC-level sata_nv 90: 1073399 145 PCI-MSI eth0 233: 10 0 IO-APIC-level ehci_hcd:usb1 NMI: 5093 2043 LOC: 922389696 922389621 ERR: 0 MIS: 0 |
有什么用
在网络非常 heavy 的情况下,对于文件服务器、高流量 Web 服务器这样的应用来说,把不同的网卡 IRQ 均衡绑定到不同的 CPU 上将会减轻某个 CPU 的负担,提高多个 CPU 整体处理中断的能力;对于数据库服务器这样的应用来说,把磁盘控制器绑到一个 CPU、把网卡绑定到另一个 CPU 将会提高数据库的响应时间、优化性能。合理的根据自己的生产环境和应用的特点来平衡 IRQ 中断有助于提高系统的整体吞吐能力和性能。
本人经常收到网友来信问到如何优化 Linux、优化 VPS、这个问题不太好回答,要记住的是性能优化是一个过程而不是结果,不是看了些文档改了改参数就叫优化了,后面还需要大量的测试、监测以及持续的观察和改进。
绑定进程到不同CPU
介绍了在 Linux 多核下如何绑定硬件中断到不同 CPU,其实也可以用类似的做法把进程手动分配到特定的 CPU 上,平时在 Linux 上运行的各种进程都是由 Linux 内核统一分配和管理的,由进程调度算法来决定哪个进程可以开始使用 CPU、哪个进程需要睡眠或等待、哪个进程运行在哪个 CPU 上等。如果你对操作系统的内核和进程调度程序感兴趣的话,不妨看看那本经典的 Operating Systems Design and Implementation(Linus Torvalds 就是看了这本书受到启发写出了 Linux),从简单的 Minix 入手,hack 内核是件很有意思的事情,本人以前修改过 Minix 内核的进程调度,学到了内核方面的很多东西。另外推荐一本课外读物:Just for Fun,Linus Torvalds 写的一本自传。
Linux 给我们提供了方便的工具用来手动分配进程到不同的 CPU 上(CPU Affinity),这样我们可以按照服务器和应用的特性来安排特定的进程到特定的 CPU 上,比如 Oracle 要消耗大量 CPU 和 I/O 资源,如果我们能分配 Oracle 进程到某个或多个 CPU 上并由这些 CPU 专门处理 Oracle 的话会毫无疑问的提高应用程序的响应和性能。还有一些特殊情况是必须绑定应用程序到某个 CPU 上的,比如某个软件的授权是单 CPU 的,如果想运行在多 CPU 机器上的话就必须限制这个软件到某一个 CPU 上。
安装 schedutils
在 CentOS/Fedora 下安装 schedutils:
# yum install schedutils |
# apt-get install schedutils |
如果正在使用 CentOS/Fedora/Debian/Ubuntu 的最新版本的话,schedutils/util-linux 这个软件包可能已经装上了。
计算 CPU Affinity 和计算 SMP IRQ Affinity 差不多:
0x00000001 (CPU0) 0x00000002 (CPU1) 0x00000003 (CPU0+CPU1) 0x00000004 (CPU2) ... |
使用 schedutils
如果想设置进程号(PID)为 12212 的进程到 CPU0 上的话:
# taskset 0x00000001 -p 12212 |