我运行一个有 24 个核心的生产 Web 服务器,其中的工作既占用 CPU 又占用 I/O,但主要是占用 CPU。当总 CPU 负载约为 85% 或更高时,我的脚本会延迟执行,以保持负载可控。因此,CPU 承受的压力永远不会超过我的脚本所能承受的范围。
现在,我的服务器在每次长达 3 小时的时间段内进行最大容量生产。大部分时间工作进展顺利,但在此期间,CPU 系统负载通常会急剧增加。这是由于内核进程“events/x”、“migration/x”和“ksoftirqd/x”造成的,其中“x”是该进程的 CPU 编号。我读到过,这表明内核正在努力处理排队任务,这种情况发生在系统负载过大的情况下。但是,正如我所提到的,我的 CPU 负载(主要瓶颈)被故意保持在约 85% 以避免此类问题。这种内核对 CPU 的使用会大大减慢生产速度,只会延长排队任务的时间。奇怪的是,大约 30 分钟后,系统负载将消失,内核进程的 CPU 使用率会降至零,但稍后又会开始占用 CPU。在这整个时间内,输入到 CPU 的工作量没有变化,通常处理得很好。然而,当这些内核进程启动时,它会完全扼杀生产。
以下是其中一个事件期间“top -u root”的输出。用户 CPU 使用率为 49%,因为系统使用率为 40%。正常情况下,用户 CPU 使用率为 ~85%,系统 CPU 使用率为 ~5%。但是,没有 iowait,系统平均负载为 22(24 个核心中),这是正常的。
top - 13:10:49 up 44 days, 20:29, 1 user, load average: 22.87, 22.73, 21.36 Tasks: 622 total, 24 running, 585 sleeping, 0 stopped, 13 zombie Cpu(s): 49.4%us, 40.3%sy, 0.0%ni, 10.1%id, 0.1%wa, 0.0%hi, 0.2%si, 0.0%st Mem: 32728060k total, 31045092k used, 1682968k free, 353768k buffers Swap: 4194300k total, 243136k used, 3951164k free, 19117436k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 51 root RT 0 0 0 0 S 11.1 0.0 436:03.06 migration/12 100 root 20 0 0 0 0 S 9.5 0.0 49:19.45 events/1 114 root 20 0 0 0 0 S 5.9 0.0 48:14.75 events/15 3 root RT 0 0 0 0 S 4.3 0.0 517:58.05 migration/0 112 root 20 0 0 0 0 S 3.6 0.0 42:00.54 events/13 27 root RT 0 0 0 0 S 2.3 0.0 200:59.58 migration/6 8149 root 20 0 165m 7732 3928 S 2.3 0.0 0:00.07 exim 15 root RT 0 0 0 0 S 2.0 0.0 450:05.62 migration/3 39 root RT 0 0 0 0 S 2.0 0.0 178:08.17 migration/9 113 root 20 0 0 0 0 S 1.6 0.0 44:00.04 events/14 178 root 20 0 0 0 0 R 1.6 0.0 53:27.57 kacpid 63 root RT 0 0 0 0 S 1.3 0.0 439:11.96 migration/15 81 root 20 0 0 0 0 S 1.0 0.0 17:14.83 ksoftirqd/19 104 root 20 0 0 0 0 S 1.0 0.0 44:58.55 events/5 115 root 20 0 0 0 0 S 1.0 0.0 47:18.46 events/16 9 root 20 0 0 0 0 S 0.7 0.0 13:56.20 ksoftirqd/1 25 root 20 0 0 0 0 S 0.7 0.0 12:46.52 ksoftirqd/5 57 root 20 0 0 0 0 S 0.7 0.0 11:12.62 ksoftirqd/13 75 root RT 0 0 0 0 S 0.7 0.0 181:00.24 migration/18 118 root 20 0 0 0 0 S 0.7 0.0 30:13.06 events/19 10497 root 20 0 77964 6244 4096 S 0.7 0.0 17:40.25 httpd
当 CPU 负载被严格控制在可管理的范围内时,这些进程的行为是否有任何可能的解释?内存不是问题,因为缓冲区/缓存的使用率从未超过系统容量的 30%。在搜索网络时,每个人都将责任归咎于过大的系统负载,但我的服务器的行为并不表明使用的资源应该导致这种锁定。
任何建议,将不胜感激。
编辑:我在答案部分发布了看似解决方案的内容。
答案1
看来内核进程可能在传输到/从交换时窃取了 CPU 时间。服务器的缓存设置在我不知情的情况下被重置,将 swappiness 设置为 60。从“sar -W”的输出来看,挂断似乎与高负载期间相吻合,在此期间 pswpin/s 和 pswpout/s 很大(大于 2.00 左右,有时高达 15.00)。将 swappiness 设置为 1 后,我没有遇到内核进程的相同挂断,并且 sar -W 始终显示接近零的值。总之,看来在高负载和大量内存传输期间的积极交换在资源需求巨大且快速变化时会拖慢系统。
答案2
migration
是负责将进程从一个 CPU 移动到另一个 CPU 的内核进程。
因此,由于某种原因,您的 Linux 调度程序决定进程需要移动到另一个 CPU,而迁移过程会占用 CPU 时间。
您可以尝试将进程固定到特定 CPU,或者尝试使用内核的不同调度程序。也许其他调度程序并不急于将进程迁移到其他 CPU。
答案3
我跟踪了迁移内核进程报告的问题这里。看来 3.6.11 之前的 Linux 内核受到了影响。链接显示了类似的症状,迁移过程占用了大量 CPU 时间。如果可能的话,您可能需要升级内核以查看问题是否仍然存在。