Skip to content

CPU负载

zhanghui edited this page Dec 16, 2016 · 2 revisions

CPU负载

CPU负载是一段时间内系统任务队列的长度,也就是,在一段时间内CPU在等待或者使用CPU。

单核心cpu就表示该cpu能够处理的事务数是1,在多核cpu中cpu能够并行处理的事务的数量应该是cpu个数*cpu核数,而且负载数最好不要超过这个数值。例如一个4核cpu,则cpu_load最大值为4,不能长期超过4,否则会有任务没有得到及时的处理,而使系统的负载累积增高,导致系统运行缓慢。

CPU利用率和CPU负载

CPU利用率显示的是程序在运行期间实时占用的CPU百分比,而CPU负载显示的是一段时间内正在使用和等待使用CPU的平均任务数。CPU利用率高,并不意味着负载就一定大。

CPU负载计算

大多数的Unix系统中的负载只是记录那些处在运行状态和可运行状态的进程,但是Linux有所不同,它会包含那些不可中断的处于睡眠状态的进程。这时当这些进程由于I/O的阻塞而不能够运行,就可能显著的增加cpu的负载。所以在Unix和Linux下的cpu的负载的计算方法是不一样的,在设定监测值的时候也需要特别考率。

kernal-2.6.32,从下面的代码特别是注释的两行可以看出,Linux记录cpu负载的时候是将cpu队列中的运行进程数和不可中断进程数都统计在内的,这样在对cpu负载分析的时候就需要考虑不可中断的进程的情况

/*
 * Either called from update_cpu_load() or from a cpu going idle
 */
static void calc_load_account_active(struct rq *this_rq)
{
	long nr_active, delta;

	nr_active = this_rq->nr_running;  //记录在cpu上运行的进程数
	nr_active += (long) this_rq->nr_uninterruptible;  //记录不可中断的进程数

	if (nr_active != this_rq->calc_load_active) {
		delta = nr_active - this_rq->calc_load_active;
		this_rq->calc_load_active = nr_active;
		atomic_long_add(delta, &calc_load_tasks);
	}
}

通常来讲有多少核就有多少负载,让CPU一直跑着,有个建议的计算方法,一个合适的负载是CPU颗数*每颗核数*0.8,但现在的服务器CPU都适用了HT技术,把一个核虚成2个,所以,可以按照颗数*核数*2*0.8,简单讲就是逻辑核数*0.8 这个0.8的值是有争议的,具体需要结合具体业务,如果本身业务就是计算密集型的,可以使用0.7或者0.8,不建议CPU长期一直满负荷运转,如果是非计算敏感型的,可以适当调高,比如0.9,1.0,确保CPU一直被占用。

对于CPU利用率和CPU Load Average的结果来判断性能问题。首先低CPU利用率不表明CPU不是瓶颈,竞争CPU的队列长期保持较长也是CPU超负荷的一种表现。对于应用来说可能会去花时间在I/O,Socket等方面,那么可以考虑是否后这些硬件的速度影响了整体的效率。

这里最好的样板范例就是我在测试中发现的一个现象:SIP当前在处理过程中,为了提高处理效率,将控制策略以及计数信息都放置在Memcached Cache里面,当我将Memcached Cache配置扩容一倍以后,CPU的利用率以及Load都有所下降,其实也就是在处理任务的过程中,等待Socket的返回对于CPU的竞争也产生了影响。

查看CPU信息

Linux系统可以使用cat /proc/cpuinfo查看CPU信息

cat /proc/cpuinfo | grep "physical id" | sort | uniq #物理CPU颗数

cat /proc/cpuinfo | grep "cpu cores" | sort | uniq #物理CPU的核数