记录一个多核CPU负载不均衡问题(动态绑定进程到指定cpu:taskset -pc $CPU $PID)

昨晚和一位读者朋友讨论了一个问题:在一台多核 CPU 的 Web 服务器上,存在负载不均衡问题,其中 CPU0 的负载明显高于其它 CPUx,进一步调查表明 PHP-FPM 的嫌疑很大。话说以前我曾经记录过软中断导致过类似的问题,但是本例中可以排除嫌疑。
让我们在一台四核服务器上采样分析一下数据确认看看是否存在负载不均衡问题:
shell> mpstat -P ALL 1 10

CPU    %usr   %nice    %sys %iowait    %irq   %soft ... %idle
all   17.57    0.03    1.78    0.00    0.35    0.23 ... 80.04
 0   43.17    0.00    4.12    0.00    1.41    1.00 ... 50.30
 1    9.80    0.00    0.81    0.00    0.00    0.00 ... 89.39
 2    9.31    0.00    1.20    0.00    0.00    0.00 ... 89.49
 3    7.94    0.10    0.80    0.00    0.00    0.00 ... 91.16

如上命令的含义是每秒运行一次 mpstat,一共采样 10 次取平均值,可以明显看出 CPU0 的空闲 idle 明显小于其它 CPUx,而且大部分都消耗在了用户态 usr 上面。
再让我们通过 pidstat 来确认一下是不是 PHP-FPM 导致的 CPU0 负载问题:
shell> pidstat | grep php-fpm | awk ‘{print $(NF-1)}‘ | sort | uniq -c

157 0
34 1
34 2
32 3

可见分配给 CPU0 的 PHP-FPM 进程比其他三个 CPUx 总和还要多。为什么大部分进程被分配给了 CPU0?我模模糊糊有一些印象是因为操作系统偏爱使用 CPU0,但我暂时也没找到实质的线索可以佐证,如果有人知道,麻烦告诉我。
问题总要解决,既然 PHP-FPM 没有类似 Nginx 那样 CPU 亲缘性(affinity)绑定的指令,那么我们可以使用 taskset 绑定 PHP-FPM 进程到固定的 CPUx 来解决问题:
#!/bin/bash

CPUs=$(grep -c processor /proc/cpuinfo)
PIDs=$(ps aux | grep "php-fpm[:] pool" | awk ‘{print $2}‘)

let i=0
for PID in $PIDs; do
   CPU=$(echo "$i % $CPUs" | bc)
   let i++

taskset -pc $CPU $PID
done

如上脚本运行后,让我们再来看看各个 CPU 负载分配情况如何:
shell> mpstat -P ALL 1 10

CPU    %usr   %nice    %sys %iowait    %irq   %soft ...  %idle
all   15.73    0.03    1.61    0.00    0.20    0.23 ...  82.20
 0   16.28    0.10    1.62    0.10    0.81    0.91 ...  80.18
 1   16.16    0.10    1.51    0.00    0.00    0.10 ...  82.13
 2   14.46    0.10    1.71    0.00    0.00    0.00 ...  83.73
 3   15.95    0.00    1.71    0.00    0.00    0.00 ...  82.35

终于平均了,不过需要提醒的是,一旦 PHP-FPM 处理的请求数超过 max_requests 的设置,那么对应的进程将自动重启,先前的 taskset 设置也将失效,所以为了一直有效,我们需要把 taskset 脚本添加到 CRON 配置中去,例如每分钟自动设置一遍!
本文把 PHP-FPM 进程平均分配给了 0,1,2,3 四个 CPU,实际操作的时候可以更灵活一些,比如前文我们提过,操作系统总是偏爱使用 CPU0,如果 CPU0 的负载已经很高了的话,那么我们不妨把 PHP-FPM 进程平均分配给 1,2,3 三个 CPU。

原文链接

时间: 2025-01-31 06:48:35

记录一个多核CPU负载不均衡问题(动态绑定进程到指定cpu:taskset -pc $CPU $PID)的相关文章

cpu负载的探讨

原链接:http://blog.chinaunix.net/uid-12693781-id-368837.html 摘要:确定cpu的负载的定义,帮助管理员设置cpu负载阀值,推测可能的导致cpu负载过高的原因,进而保证服务器的正常运行. 1.cpu负载的定义 首先,看看cpu负载的定义.在一般情况下可以将单核心cpu的负载看成是一条单行的桥,数字1代表cpu刚好能够处理过来,即桥上能够顺利通过所有的车辆, 桥外没有等待的车辆,桥是畅通的.当超过1时表示有等待上桥的车辆,小于1时表示车辆能够快速

如何获取多核、多cpu系统中指定cpu的序列号

如何获取多核.多cpu系统中指定cpu的序列号作者:SkyJacker(转贴请保持完整并注明作者和出处)http://www.cnpack.orgCnPack IV  QQ Group: 1309702007-01-23 感谢:Passion,Bahamut,早安,空气,SkyJacker...没有Bahamut的奇思妙点,就没有这片文章. 在多cpu.多核中,会随机的获得不同的序列号.这就为我们根据cpu序列号来制作注册机带来了很大的麻烦.Windows 2000/xp允许设置进程和线程的亲缘

python-检测cpu负载

近期研究nagios,特意写了检测cpu负载的python脚本(有借鉴网上资料),顺道练练python脚本,以下采用2种方法获取cpu负载. 1.读取cpu负载文件: #!/usr/bin/env python#-*- coding:utf-8 -*-'''cpu负载检测 for nagios'''import sysdef check_load():    loadf=open('/proc/loadavg','r')    allavg=loadf.readline()    load5av

linux上限制用户进程数、cpu占用率、内存使用率

限制进程CPU占用率的问题,给出了一个shell脚本代码如下: renice +10 `ps aux | awk '{ if ($3 > 0.8 && id -u $1 > 500) print $2}'` 其中用到ps获取进程信息,其实 ps中%CPU一列的意义是进程实际占有CPU时间和它存活时间的比值,这个值能反应进程对CPU的消耗,但不能准确反应进程所占CPU时间占整个系统CPU的百分比. 而top输出中的%CPU这一列正是进程所占CPU时间占整个系统CPU的百分比,用于

LINUX内核CPU负载均衡机制【转】

转自:http://oenhan.com/cpu-load-balance 还是神奇的进程调度问题引发的,参看Linux进程组调度机制分析,组调度机制是看清楚了,发现在重启过程中,很多内核调用栈阻塞在了double_rq_lock函数上,而double_rq_lock则是load_balance触发的,怀疑当时的核间调度出现了问题,在某个负责场景下产生了多核互锁,后面看了一下CPU负载平衡下的代码实现,写一下总结. 内核代码版本:kernel-3.0.13-0.27. 内核代码函数起自load_

CPU负载均衡uptime参数

一.uptime参数: 1.[[email protected] ~]$ uptime      20:00:16 up 2 min,  1 user,  load average: 0.55, 0.70, 0.30 服务器运行时间      负载均衡     1分钟  5分钟  15分钟 2.形象图解:3.cpu过载的经验参考值:最好不要超过CPU的核数 单核的负载均衡临界点:3-5之间.双核的:8-10之间.实际还以具体的业务为准

一个简单的负载均衡的示例

参考地址:http://www.nginx.cn/doc/example/loadbanlance.html 一个简单的负载均衡的示例,把www.domain.com均衡到本机不同的端口,也可以改为均衡到不同的地址上.> http { : upstream myproject { : server 127.0.0.1:8000 weight=3; : server 127.0.0.1:8001; : server 127.0.0.1:8002; : server 127.0.0.1:8003;

【原创】(二)Linux进程调度器-CPU负载

背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本:4.14 ARM64处理器,Contex-A53,双核 使用工具:Source Insight 3.5, Visio 1. 概述 CPU负载(cpu load)指的是某个时间点进程对系统产生的压力. 来张图来类比下(参考Understanding Linux CPU Load) CPU的运行能力,就

CentOS下通过命令行制造CPU负载或压力

无意间在51首页上看到一篇关于"通过命令行制造CPU负载或压力"的文章,感觉不错,先记录下来,为将来的使用做好笔记记录!     很简单,就一个命令:    # cat /dev/urandom | md5sum