原文地址:https://www.douyacun.com/article/aac2ceebe1b2d3d706620a193feb580e
负载首先看的是top(htop也可以),可以定位到是哪个进程(线上服务也不会运行多个服务的)
但是进程是因为什么导致的进程负载高?
单核处理器
"load average"的值越低,比如等于0.2或0.3,就说明电脑的工作量越小,系统负荷比较轻。
系统负荷为1.0,意味着大桥的所有路段都有车,也就是说大桥已经"满"了。但是必须注意的是,直到此时大桥还是能顺畅通行的
系统负荷为1.7,意味着车辆太多了,大桥已经被占满了(100%),后面等着上桥的车辆为桥面车辆的70%。
CPU的系统负荷,基本上等同于上面的类比。大桥的通行能力,就是CPU的最大工作量;桥梁上的车辆,就是一个个等待CPU处理的进程(process)。
经验法则
当系统负荷持续大于0.7,你必须开始调查了,问题出在哪里,防止情况恶化。
当系统负荷持续大于1.0,你必须动手寻找解决办法,把这个值降下来。
当系统负荷达到5.0,就表明你的系统有很严重的问题,长时间没有响应,或者接近死机了。你不应该让系统达到这个值。
多处理器
2个CPU表明系统负荷可以达到2.0,此时每个CPU都达到100%的工作量。推广开来,n个CPU的电脑,可接受的系统负荷最大为n.0
其他工具用法: 高负载定位的常用工具以及用法分析
详细用法来自: sparkdev
-v
: verbose 详情
-q
: quiet 程序在运行的过程中不输出信息
-n
: dry-run 演练,并不实际执行
-t
: timeout 超时
-c
: 多少进程计算sqrt(平方根)
-i
: 多少进程调用sync(脏页同步到磁盘)
-m
: 多少进程调用内存malloc/free(内存申请释放)
--vm-bytes B
每个进程总计申请多少字节内存
--vm-stride B
内存赋值时间隔多少字节
不断的给部分内存赋值,让 COW(Copy On Write)发生。只要指定了内存相关的选项,这个操作就会执行,只是大小为默认的 4096。赋值内存的比例由参数决定:
for (i = 0; i < bytes; i += stride)
ptr[i] = 'Z'; /* Ensure that COW happens. */
bytes 为消耗的总内存大小,stride 为间隔。 该参数会影响 CPU 状态 us 和 sy:
$ stress --vm 2 --vm-bytes 500M --vm-stride 64
$ top
%Cpu(s): 21.3 us, 32.1 sy
$ stress --vm 2 --vm-bytes 500M --vm-stride 1M
$ top
%Cpu(s): 0.7 us, 36.3 sy
--vm-stride
值增大就意味着减少赋值,用户空间占用CPU的比率就小了--vm-hang N
: 每个消耗内存的进程在分配到内存后转入睡眠状态 N 秒,然后释放内存,一直重复执行这个过程, CPU空闲出来了,US就会降低了--vm-keep
: 一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存)$ stress --vm 2 --vm-bytes 500M --vm-keep
%Cpu(s): 50.4 us, 0.3 sy
$ stress --vm 2 --vm-bytes 500M --vm-hang 5
%Cpu(s): 1.8 us, 7.8 sy
-d
: (--hadd
) 产生 N 个不断执行 write 和 unlink 函数的进程(创建文件,写入内容,删除文件)
--hadd-bytes B
指定文件大小$ stress -d 3 --hdd-bytes 10M
$ pidstat -d 3
11时34分30秒 UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
11时34分33秒 1000 20879 0.00 1.33 0.00 java
11时34分33秒 0 23086 0.00 308237.87 309581.40 stress
11时34分33秒 0 23087 0.00 346640.53 347003.32 stress
11时34分33秒 0 23088 0.00 329619.93 326591.36 stress
$ stress -c 1 time 600
$ watch -d uptime
Every 2.0s: uptime
23:39:14 up 10 days, 15:03, 3 users, load average: 1.17, 0.82, 0.40
$ mpstat -P ALL 5
23时35分39秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
23时35分44秒 all 26.35 0.00 1.00 0.00 0.00 0.05 0.00 0.00 0.00 72.60
23时35分44秒 0 0.60 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 98.40
23时35分44秒 1 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23时35分44秒 2 3.41 0.00 1.41 0.00 0.00 0.00 0.00 0.00 0.00 95.18
23时35分44秒 3 1.21 0.00 1.61 0.00 0.00 0.00 0.00 0.00 0.00 97.18
CPU密集型是因为进程进行了大量的运算工作的导致的,通过mpstat
可以轻松判断出来、
todo: 如何对代码定位问题
特点:
usr
高,进程一直处于用户态运行sys
低iowait
低$ stress -i 5 --timeout 600
$ watch -d uptime
Every 2.0s: uptime Sat Aug 8 00:18:56 2020
00:18:56 up 10 days, 15:43, 3 users, load average: 0.95, 0.75, 0.43
$ mpstat -P ALL 3
13时42分04秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
13时42分07秒 all 2.04 0.00 43.20 1.02 0.00 0.09 0.00 0.00 0.00 53.66
13时42分07秒 0 4.10 0.00 42.66 0.00 0.00 0.00 0.00 0.00 0.00 53.24
13时42分07秒 1 0.68 0.00 43.69 0.34 0.00 0.00 0.00 0.00 0.00 55.29
13时42分07秒 2 2.03 0.00 42.23 0.34 0.00 0.00 0.00 0.00 0.00 55.41
13时42分07秒 3 1.70 0.00 44.22 3.06 0.00 0.00 0.00 0.00 0.00 51.02
$ top
top - 13:49:30 up 12 days, 5:13, 5 users, load average: 2.07, 1.08, 1.44
Tasks: 169 total, 1 running, 168 sleeping, 0 stopped, 0 zombie
%Cpu(s): 2.9 us, 41.4 sy, 0.0 ni, 55.0 id, 0.5 wa, 0.0 hi, 0.1 si, 0.0 st
KiB Mem : 7924044 total, 1278284 free, 5345032 used, 1300728 buff/cache
KiB Swap: 2097148 total, 2095868 free, 1280 used. 2109988 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3092 root 20 0 7308 96 0 D 28.2 0.0 0:09.30 stress
3094 root 20 0 7308 96 0 D 27.9 0.0 0:09.37 stress
3091 root 20 0 7308 96 0 D 27.6 0.0 0:09.36 stress
3093 root 20 0 7308 96 0 D 27.6 0.0 0:09.31 stress
3095 root 20 0 7308 96 0 D 26.9 0.0 0:09.35 stress
I/O密集型是因为进行了大量的磁盘读写导致的负载高,其实磁盘和内存之间是有 页缓存 来缓冲磁盘和内存速度差异的,
iowait
偏高的,iowait
高的原因是因为调用 sync
/ fsync
频繁的刷新脏页导致iowait过高,此时是处于内核态运行的所以 sys
也会偏高iowait
/sys
会较高而上面sys
较高,iowait
低的原因,只是因为高频的调用了sync
,没有脏页(没有高频的写文件)
$ stress -c 8
$ watch -d uptime
Every 2.0s: uptime Sun Aug 9 13:19:04 2020
13:19:05 up 12 days, 4:43, 5 users, load average: 7.44, 3.23, 1.30
$ mpstat -P ALL 3
14时32分28秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
14时32分31秒 all 99.42 0.00 0.58 0.00 0.00 0.00 0.00 0.00 0.00 0.00
14时32分31秒 0 99.67 0.00 0.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00
14时32分31秒 1 98.00 0.00 2.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
14时32分31秒 2 99.67 0.00 0.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00
14时32分31秒 3 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
$ pidstat -u 3
14时32分56秒 UID PID %usr %system %guest %CPU CPU Command
14时32分59秒 0 19290 0.00 0.33 0.00 0.33 3 mpstat
14时32分59秒 0 19450 0.33 1.33 0.00 1.67 0 pidstat
14时32分59秒 0 19491 48.67 0.00 0.00 48.67 3 stress
14时32分59秒 0 19492 49.33 0.00 0.00 49.33 1 stress
14时32分59秒 0 19493 48.67 0.00 0.00 48.67 3 stress
14时32分59秒 0 19494 48.67 0.00 0.00 48.67 0 stress
14时32分59秒 0 19495 50.33 0.00 0.00 50.33 2 stress
14时32分59秒 0 19496 48.67 0.00 0.00 48.67 0 stress
14时32分59秒 0 19497 49.33 0.00 0.00 49.33 2 stress
14时32分59秒 0 19498 49.33 0.33 0.00 49.67 1 stress
$ vmstat 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
8 0 1280 1271004 148 1301392 0 0 0 1 5 1 2 1 97 0 0
8 0 1280 1271000 148 1301380 0 0 0 3 4414 1760 98 2 0 0 0
8 0 1280 1267432 148 1301368 0 0 0 0 4370 1636 98 2 0 0 0
系统是4H8G
usr
一直是100%r
正在运行的进程队列是 8使用sysbench模拟大量的线程
$ sysbench --threads=10 --time=10 threads run
top - 09:18:26 up 14 days, 42 min, 2 users, load average: 2.58, 0.66, 1.30
Tasks: 161 total, 1 running, 160 sleeping, 0 stopped, 0 zombie
%Cpu(s): 16.2 us, 76.0 sy, 0.0 ni, 7.8 id, 0.0 wa, 0.0 hi, 0.1 si, 0.0 st
KiB Mem : 7924044 total, 1689024 free, 5740484 used, 494536 buff/cache
KiB Swap: 2097148 total, 1800444 free, 296704 used. 1734212 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
7640 root 20 0 95116 3972 2824 S 351.5 0.1 1:41.20 sysbench
$ vmstat -S M 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
6 0 289 1649 0 482 0 0 1 3 8 1 2 1 97 0 0
7 0 289 1649 0 482 0 0 0 1 23407 347642 14 76 9 0 0
7 0 289 1648 0 482 0 0 0 0 21909 339189 16 76 8 0 0
7 0 289 1649 0 482 0 0 0 0 23330 344468 16 75 9 0 0
$ pidstat -p 7640 -wt 3
09时21分22秒 UID TGID TID cswch/s nvcswch/s Command
09时21分25秒 0 7640 - 0.00 0.00 sysbench
09时21分25秒 0 - 7640 0.00 0.00 |__sysbench
09时21分25秒 0 - 7641 8870.00 23660.33 |__sysbench
09时21分25秒 0 - 7642 10428.00 20367.67 |__sysbench
09时21分25秒 0 - 7643 10766.67 19406.67 |__sysbench
09时21分25秒 0 - 7644 10391.67 18603.00 |__sysbench
09时21分25秒 0 - 7645 10480.00 21960.33 |__sysbench
09时21分25秒 0 - 7646 10012.67 18224.00 |__sysbench
09时21分25秒 0 - 7647 9655.00 18724.33 |__sysbench
09时21分25秒 0 - 7648 10216.33 20583.00 |__sysbench
09时21分25秒 0 - 7649 10317.67 20421.00 |__sysbench
09时21分25秒 0 - 7650 10450.67 20246.67 |__sysbench
通过top知道负载高的原因
vmstat定位负载高的原因:
pidstat定位负载高的原因:
分析
CPU使用率高定位是哪个进程,我们可以使用的工具有:
如何定位是进程的哪个函数导致的?