昨晚和一位读者朋友讨论了一个问题:在一台多核 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。

原文链接

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

  1. 有趣的taskset命令,使进程再指定CPU上运行

    前言 taskset命令,用于进程的CPU调优,可以把某进程,指定再某CPU内工作. 如还不明白,可以参考此文 http://www.361way.com/linux-context-switch/5 ...

  2. cpu负载的探讨 (转)

    文章出处:http://blog.chinaunix.net/uid-12693781-id-368837.html 摘要:确定cpu的负载的定义,帮助管理员设置cpu负载阀值,推测可能的导致cpu负 ...

  3. cpu负载的探讨

    原链接:http://blog.chinaunix.net/uid-12693781-id-368837.html 摘要:确定cpu的负载的定义,帮助管理员设置cpu负载阀值,推测可能的导致cpu负载 ...

  4. eCos系统CPU负载测量

    原文:http://ecos.sourceware.org/docs-latest/ref/services-cpuload.html 译文:http://blog.csdn.net/zoomdy/a ...

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

    如何获取多核.多cpu系统中指定cpu的序列号作者:SkyJacker(转贴请保持完整并注明作者和出处)http://www.cnpack.orgCnPack IV  QQ Group: 130970 ...

  6. Process和Thread在指定CPU运行

    最近帮朋友写了一个多线程程序,他那边一运行多线程就出错,我这边却没有任何问题,找了好久才找到解决方法,原来是CPU的问题,有朋友遇到同样的问题,可以一起参考 //进程与指定cpu绑定 SetProce ...

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

    限制进程CPU占用率的问题,给出了一个shell脚本代码如下: renice +10 `ps aux | awk '{ if ($3 > 0.8 && id -u $1 > ...

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

    转自:http://oenhan.com/cpu-load-balance 还是神奇的进程调度问题引发的,参看Linux进程组调度机制分析,组调度机制是看清楚了,发现在重启过程中,很多内核调用栈阻塞在 ...

  9. 一个快速检测系统CPU负载的小程序

    原理说明 在对服务器进行维护时,有时也遇到由于系统 CPU(利用率)负载过高导致业务中断的情况.服务器上可能运行多个进程,查看单个进程的 CPU 都是正常的,但是整个系统的 CPU 负载可能是异常的. ...

随机推荐

  1. MSSQL 判断一个时间段是否在另一个时间段内!

    MSSQL 判断一个时间段是否在另一个时间段内! 1 CREATE TABLE #B ( MeetingRoom int, BeginTime datetime, EndTime datetime ) ...

  2. [platform]linux platform device/driver(三)--Platform Device和Platform_driver注册过程之代码对比

    转自:http://blog.csdn.net/thl789/article/details/6723350 Linux 2.6的设备驱动模型中,所有的device都是通过Bus相连.device_r ...

  3. 使用它tshark分析pcap的例子以及scapy下载地址

    转一篇cisco工作人员使用tshark分析pcap的文章,以及scapy的下载地址 http://blogs.cisco.com/security/finding-a-needle-in-a-pca ...

  4. php 读取文件readfile

    <?php //读取文件 //echo readfile('aa.txt'); //打开文件更好的方法是fopen $f = fopen('aa.txt' , 'r') or die('unab ...

  5. sysbench压力测试工具简介和使用(一)

    sysbench压力测试工具安装和参数介绍 一.sysbench压力测试工具简介: sysbench是一个开源的.模块化的.跨平台的多线程性能测试工具,可以用来进行CPU.内存.磁盘I/O.线程.数据 ...

  6. javascript的事件

    前戏 今天在博客中看到了javascript的事件机制,就自己试试写一个简单的冒泡捕获测试,但是测试结果出乎了我的意料,主要是自己原来对事件了解不是很清楚,现在写篇博客记录下. 基础 先来看一下我在A ...

  7. php rmdir使用递归函数删除非空目录

    我们大家都知道,php rmdir()函数用于删除空目录,但如果要删除非空目录,我们必须将非空目录中的文件或子目录删除,本文章向大家介绍php如何使用递归函数删除非空目录,需要的朋友可以参考一下.首先 ...

  8. spring mvc定时任务的简单使用

    版权声明:本文为楼主原创文章,未经楼主允许不得转载,如要转载请注明来源. 说起定时任务,开发的小伙伴们肯定不陌生了.有些事总是需要计算机去完成的,而不是傻傻的靠我们自己去.可是好多人对定时器总感觉很陌 ...

  9. 洛谷P3366 【模板】最小生成树

    P3366 [模板]最小生成树 319通过 791提交 题目提供者HansBug 标签 难度普及- 提交  讨论  题解 最新讨论 里面没有要输出orz的测试点 如果你用Prim写了半天都是W- 题目 ...

  10. Android软件更新安装。

    app的开发有一个问题是避免不了的,那就是软件的升级维护. 这里我在查过一些资料和写了一个升级帮助类.使用很方便.直接导入就可以了. ( VersionBean.class为更新地址返回的数据对象,我 ...