linux 查当前pid_linux系统load高让人摸不着头脑

近期遇到两次系统周期性地 load升高,但业务流量并没有上升,系统cpu、内存、I/O负载也不高,到底是什么原因造成的,是否因为底层异常?
要弄清 Linux 虚机 load 高,我们要搞清楚 Linux top 命令中 Load 的含义。

Load average 的值从何而来:

在使用 top 命令检查系统负载的时候,可以看到 Load averages 字段,但是这个字段并不是表示 CPU 的繁忙程度,而是度量系统整体负载。
Load averages 采样是从 /proc/loadavg 中获取的:

0.00 0.01 0.05 1/161 29703 每个值的含义依次为: 

lavg_1 (0.00) 1- 分钟平均负载 

lavg_5 (0.01) 5- 分钟平均负载 

lavg_15(0.05) 15- 分钟平均负载 

nr_running (1) 在采样时刻,运行队列的任务的数目,与/proc/stat的 procs_running表示相同意思,这个数值是当前可运行的内核调度对象(进程,线程)。nr_threads (161) 在采样时刻,系统中活跃的任务的个数(不包括运行已经结束的任务),即这个数值表示当前存在系统中的内核可调度对象的数量。last_pid(29703) 系统最近创建的进程的 PID,包括轻量级进程,即线程。假设当前有两个 CPU,则每个 CPU 的当前任务数为 0.00/2=0.00

如果你看到 load average 数值是 10,则表明平均有 10 个进程在运行或等待状态。有可能系统有很高的负载但是 CPU 使用率却很低,或者负载很低而 CPU 利用率很高,因为这两者没有直接关系。

 关于源码中这块的说明:

e064ce4af317bb9206a627de5f2a044e.png

742d82f00c8036e0bd77531ae2423214.png

4575f44d774bf69299f22ede3eec0069.png

0b51a5416027b7dc11aceb0a5174575e.png

从这个函数中可以看到,内核计算load采用的是一种平滑移动的算法,Linux的系统负载指运行队列的平均长度,需要注意的是:可运行的进程是指处于运行队列的进程,不是指正在运行的进程。即进程的状态是TASK_RUNNING或者TASK_UNINTERRUPTIBLE。
Linux 内核定义一个长度为 3 的双字数组 avenrun,双字的低 11 位用于存放负载的小数部分,高 21 位用于存放整数部分。当进程所耗的 CPU 时间片数超过 CPU 在 5秒内能够提供的时间片数时,内核计算上述的三个负载,负载初始化为 0。假设最近 1、5、15 分钟内的平均负载分别为 load1、load5 和 load15,那么下一个计算时刻到来时,内核通过下面的算式计算负载:
load1 -= load1 - exp(-5 / 60) -+ n (1 - exp(-5 / 60 ))
load5 -= load5 - exp(-5 / 300) + n (1 - exp(-5 / 300))
load15 = load15 exp(-5 / 900) + n (1 - exp(-5 / 900))
其中,exp(x) 为 e 的 x 次幂,n 为当前运行队列的长度。

如何找出系统中 load 高时处于运行队列的进程:

通过前面的讲解,我们已经明白有可能系统有很高的负载但是CPU使用率却很低,或者负载很低而 CPU 利用率很高,这两者没有直接关系,如何用脚本统计出来处于运行队列的进程呢?

每秒统计一次:

2a05e2330456d89418a3f1b16ec7a98b.png

从统计出来的结果可以看到:

f2a2c4a5c36c78196a28cec7a2d727aa.png

注:R 代表运行中的队列,D 是不可中断的睡眠进程。

在 load 比较高的时候,有大量的进程处于R或者D状态,他们才是造成 load 上升的元凶,和我们底层的负载确实是没有关系的:

补充:

查 CPU 使用率比较高的线程小脚本:

75a9697fb99594ba8ab59560a7473339.png

如果 load 较高,触发了Linux内核Lockup,该如何处理以及优化呢:

具体日志输出如下:

caf35dc2e481a6ec332c3a0f03849ac4.png

Linux内核Lockup就是linux内核占用CPU不放,Lockup分为两种:

soft lockup 和 hard lockup。

soft lockup是指CPU被内核代码占据,以至于无法执行其它进程。检测soft lockup的原理是给每个CPU分配一个定时执行的内核线程[watchdog/x],

如果该线程在设定的期限内没有得到执行的话就意味着发生了soft lockup,[watchdog/x]是SCHED_FIFO实时进程,优先级为最高的99,拥有优先运行的特权。

hard lockup比soft lockup更加严重,CPU不仅无法执行其它进程,而且不再响应中断。检测hard lockup的原理利用了PMU的NMI perf event,

因为NMI中断是不可屏蔽的,在CPU不再响应中断的情况下仍然可以得到执行,它再去检查时钟中断的计数器hrtimer_interrupts是否在保持递增,

如果停滞就意味着时钟中断未得到响应,也就是发生了hard lockup。

linux内核的代码实现在kernel/watchdog.c中:

主体涉及到了3个东西:kernel线程,时钟中断,NMI中断(不可屏蔽中断)。这3个东西具有不一样的优先级,依次是kernel线程 < 时钟中断 < NMI中断。

检测机制

Linux kernel设计了一个检测lockup的机制,称为NMI Watchdog,是利用NMI中断实现的,用NMI是因为lockup有可能发生在中断被屏蔽的状态下,这时唯一能把CPU抢下来的方法就是通过NMI,因为NMI中断是不可屏蔽的。NMI Watchdog 中包含 soft lockup detector 和 hard lockup detector,2.6之后的内核的实现方法如下。

NMI Watchdog 的触发机制包括两部分:

1. 一个高精度计时器(hrtimer),对应的中断处理例程是kernel/watchdog.c: watchdog_timer_fn(),在该例程中:

  • 要递增计数器hrtimer_interrupts,这个计数器供hard lockup detector用于判断CPU是否响应中断;

  • 要唤醒[watchdog/x]内核线程,该线程的任务是更新一个时间戳;

  • soft lock detector检查时间戳,如果超过soft lockup threshold一直未更新,说明[watchdog/x]未得到运行机会,意味着CPU被霸占,也就是发生了soft lockup。

2.基于PMU的NMI perf event,当PMU的计数器溢出时会触发NMI中断,对应的中断处理例程是 kernel/watchdog.c: watchdog_overflow_callback(),

hard lockup detector就在其中,它会检查上述hrtimer的中断次数(hrtimer_interrupts)是否在保持递增,如果停滞则表明hrtimer中断未得到响应,也就是发生了hard lockup。

参数设定

hrtimer的周期是:softlockup_thresh/5。

  • 在2.6内核中:
    softlockup_thresh的值等于内核参数kernel.watchdog_thresh,默认60秒;

  • 而到3.10内核中:
    内核参数kernel.watchdog_thresh名称未变,但含义变成了hard lockup threshold,默认10秒;
    soft lockup threshold则等于(2*kernel.watchdog_thresh),即默认20秒。

NMI perf event是基于PMU的,触发周期(hard lockup threshold)在2.6内核里是固定的60秒,不可手工调整;在3.10内核里可以手工调整,

因为直接对应着内核参数kernel.watchdog_thresh,默认值10秒。

处理方式

目前遇到Linux内核Lockup的主机,CPU频率调节模式都是ondemand模式。该模式是系统默认的超频模式,按需调节,内核提供的功能,不是很强大。

各种模式说明:

b866546918cb8ec3a85339457dd2fce1.png

查看当前cpu频率:

cat /proc/cpuinfo | grep -i "cpu mhz"

0b9a15ca3060ced6f71e9cd994c40b85.png

修改方法,建议从bios中修改,由于不同厂家的主机操作有所不同,这里就不一一列举.

centos7系统层面修改如下:

查看当前cpu策略

cpupower frequency-info --policy

修改策略

cpupower frequency-set -g performance

实时查看cpu频率

watch -n 1 "cat /proc/cpuinfo | grep MHz"

#使用的intel驱动

/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver

#intel_pstate驱动详细信息

/sys/devices/system/cpu/intel_pstate/

#各种频率相关

/sys/devices/system/cpu/cpu0/cpufreq/

#查看当前cpu策略

/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

修改后如下:

2e5e04d9fa3452246a78e63ce0e80f84.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值