简介: 压测时或多或少都收到过CPU或者Load高的告警,如果是单机偶发性的,常常会认为是“宿主机抢占导致的”,那事实是否真是如此呢?是什么引起了这些指标的飙高?网络、磁盘还是高并发?有什么工具能够定位?TOP、PS还是vmstat?CPU高&Load高和CPU低&Load高,不同的表征又代表着什么?
一 背景常识
LINUX过程状态
LINUX 2.6当前的内核中,过程个别存在7种根底状态:D-不可中断睡眠、R-可执行、S-可中断睡眠、T-暂停态、t-跟踪态、X-死亡态、Z-僵尸态,这几种状态在PS命令中有对应解释。
- D (TASK_UNINTERRUPTIBLE),不可中断睡眠态。顾名思义,位于这种状态的过程处于睡眠中,并且不容许被其余过程或中断(异步信号)打断。因而这种状态的过程,是无奈应用kill -9杀死的(kill也是一种信号),除非重启零碎(没错,就是这么头硬)。不过这种状态个别由I/O期待(比方磁盘I/O、网络I/O、外设I/O等)引起,呈现工夫十分短暂,大多很难被PS或者TOP命令捕捉(除非I/O HANG死)。SLEEP态过程不会占用任何CPU资源。
- R (TASK_RUNNING),可执行态。这种状态的过程都位于CPU的可执行队列中,正在运行或者正在期待运行,即不是在下班就是在下班的路上。
- S (TASK_INTERRUPTIBLE),可中断睡眠态。不同于D,这种状态的过程尽管也处于睡眠中,然而是容许被中断的。这种过程个别在期待某事件的产生(比方socket连贯、信号量等),而被挂起。一旦这些工夫实现,过程将被唤醒转为R态。如果不在高负载期间,零碎中大部分过程都处于S态。SLEEP态过程不会占用任何CPU资源。
- T&t (__TASK_STOPPED & __TASK_TRACED),暂停or跟踪态。这种两种状态的过程都处于运行进行的状态。不同之处是暂停态个别因为收到SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOUT四种信号被进行,而跟踪态是因为过程被另一个过程跟踪引起(比方gdb断点)。暂停态过程会开释所有占用资源。
- Z (EXIT_ZOMBIE), 僵尸态。这种状态的过程实际上曾经完结了,然而父过程还没有回收它的资源(比方过程的描述符、PID等)。僵尸态过程会开释除过程入口之外的所有资源。
- X (EXIT_DEAD), 死亡态。过程的真正完结态,这种状态个别在失常零碎中捕捉不到。
Load Average & CPU使用率
谈到零碎性能,Load和CPU使用率是最直观的两个指标,那么这两个指标是怎么被计算出来的呢?是否能相互等价呢?
Load Average
不少人都认为,Load代表正在CPU上运行&期待运行的过程数,即
但Linux零碎中,这种形容并不齐全精确。
以下为Linux内核源码中Load Average计算方法,能够看进去,因而除了可执行态过程,不可中断睡眠态过程也会被一起纳入计算,即:
602staticunsignedlongcount_active_tasks(void)603 {604structtask_struct*p;605unsignedlongnr=0;606607read_lock(&tasklist_lock);608for_each_task(p) {609if ((p->state==TASK_RUNNING610 (p->state&TASK_UNINTERRUPTIBLE)))611nr+=FIXED_1;612 }613read_unlock(&tasklist_lock);614returnnr;615 }......625staticinlinevoidcalc_load(unsignedlongticks)626 {627unsignedlongactive_tasks; /* fixed-point */628staticintcount=LOAD_FREQ;629630count-=ticks;631if (count<0) {632count+=LOAD_FREQ;633active_tasks=count_active_tasks();634CALC_LOAD(avenrun[0], EXP_1, active_tasks);635CALC_LOAD(avenrun[1], EXP_5, active_tasks);636CALC_LOAD(avenrun[2], EXP_15, active_tasks);637 }638 }
在前文 Linux过程状态 中有提到过,不可中断睡眠态的过程(TASK_UNINTERRUTED)个别都在进行I/O期待,比方磁盘、网络或者其余外设期待。由此咱们能够看出,Load Average在Linux中体现的是整体零碎负载,即CPU负载 + Disk负载 + 网络负载 + 其余外设负载,并不能齐全等同于CPU使用率(这种状况只呈现在Linux中,其余零碎比方Unix,Load还是只代表CPU负载)。
CPU使用率
CPU的工夫分片个别可分为4大类:用户过程运行工夫 - User Time, 零碎内核运行工夫 - System Time, 闲暇工夫 - Idle Time, 被抢占工夫 - Steal Time。除了Idle Time外,其余工夫CPU都处于工作运行状态。
通常而言,咱们泛指的整体CPU使用率为User Time 和 Systime占比之和(例如tsar中CPU util),即:
为了便于定位问题,大多数性能统计工具都将这4类工夫片进一步细化成了8类,如下为TOP对CPU工夫片的分类。
- us:用户过程空间中未扭转过优先级的过程占用CPU百分比
- sy:内核空间占用CPU百分比
- ni:用户过程空间内扭转过优先级的过程占用CPU百分比
- id:闲暇工夫百分比
- wa:闲暇&期待I/O的工夫百分比
- hi:硬中断工夫百分比
- si:软中断工夫百分比
- st:虚拟化时被其余VM窃取工夫百分比
这8类分片中,除wa和id外,其余分片CPU都处于工作态。
二 资源&瓶颈剖析
从上文咱们理解到,Load Average和CPU使用率可被细分为不同的子域指标,指向不同的资源瓶颈。总体来说,指标与资源瓶颈的对应关系根本如下图所示。
Load高 & CPU高
这是咱们最常遇到的一类状况,即load上涨是CPU负载回升导致。依据CPU具体资源分配体现,可分为以下几类:
CPU sys高
这种状况CPU次要开销在于零碎内核,可进一步查看上下文切换状况。
- 如果非被迫上下文切换较多,阐明CPU抢占较为强烈,大量过程因为工夫片已到等起因,被零碎强制调度,进而产生的上下文切换。
- 如果被迫上下文切换较多,阐明可能存在I/O、内存等系统资源瓶颈,大量过程无奈获取所需资源,导致的上下文切换。
CPU si高
这种状况CPU大量耗费在软中断,可进一步查看软中断类型。一般而言,网络I/O或者线程调度引起软中断最为常见:
- NET_TX & NET_RX。NET_TX是发送网络数据包的软中断,NET_RX是接管网络数据包的软中断,这两种类型的软中断较高时,零碎存在网络I/O瓶颈可能性较大。
- SCHED。SCHED为过程调度以及负载平衡引起的中断,这种中断呈现较多时,零碎存在较多过程切换,个别与非被迫上下文切换高同时呈现,可能存在CPU瓶颈。
CPU us高
这种状况阐明资源次要耗费在利用过程,可能引发的起因有以下几类:
- 死循环或代码中存在CPU密集计算。这种状况多核CPU us会同时上涨。
- 内存问题,导致大量FULLGC,阻塞线程。这种状况个别只有一核CPU us上涨。
- 资源期待造成线程池满,连带引发CPU上涨。这种状况下,线程池满等异样会同时呈现。
Load高 & CPU低
这种状况呈现的根本原因在于不可中断睡眠态(TASK_UNINTERRUPTIBLE)过程数较多,即CPU负载不高,但I/O负载较高。可进一步定位是磁盘I/O还是网络I/O导致。
三 排查策略
利用现有罕用的工具,咱们罕用的排查策略根本如下图所示:
从问题发现到最终定位,根本可分为四个阶段:
资源瓶颈定位
这一阶段通过全局性能检测工具,初步定位资源耗费异样位点。
罕用的工具有:
- top、vmstat、tsar(历史)
- 中断:/proc/softirqs、/proc/interrupts
- I/O:iostat、dstat
热点过程定位
定位到资源瓶颈后,可进一步剖析具体过程资源耗费状况,找到热点过程。
常用工具有:
- 上下文切换:pidstat -w
- CPU:pidstat -u
- I/O:iotop、pidstat -d
- 僵尸过程:ps
线程&过程外部资源定位
找到具体过程后,可细化剖析过程外部资源开销状况。
常用工具有:
- 上下文切换:pidstat -w -p [pid]
- CPU:pidstat -u -p [pid]
- I/O: lsof
热点事件&办法剖析
获取到热点线程后,咱们可用trace或者dump工具,将线程反向关联,将问题范畴定位到具体方法&堆栈。
罕用的工具有:
- perf:Linux自带性能剖析工具,性能相似hotmethod,基于事件采样原理,以性能事件为根底,反对针对处理器相干性能指标与操作系统相干性能指标的性能分析。
- jstack
- 联合ps -Lp或者pidstat -p一起应用,可初步定位热点线程。
- 联合zprofile-threaddump一起应用,可统计线程散布、等锁状况,罕用与线程数减少剖析。
- strace:跟踪过程执行时的零碎调用和所接管的信号。
- tcpdump:抓包剖析,罕用于网络I/O瓶颈定位。
相干浏览
[1]Linux Load Averages: Solving the Mystery
http://www.brendangregg.com/blog/2017-08-08/linux-load-averages.html
[2]What exactly is a load average?
http://linuxtechsupport.blogspot.com/2008/10/what-exactly-is-load-average.html