从我球docs粘过来的,不想写两份,看着乱的,直接看最后的结论
uptime查看系统瓶颈负载
[root /home/user]# uptime
13:11:01 up 888 days, 21:33, 8 users, load average: 17.20, 14.85, 14.10
lscpu查看 CPU 信息:
[root@Tencent-SNG /home/user_00]# lscpu
Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 32 On-line CPU(s) list: 0-31 Thread(s) per core: 2 Core(s) per socket: 8 Socket(s): 2 NUMA node(s): 2 Vendor ID: GenuineIntel CPU family: 6 Model: 62 Stepping: 4 CPU MHz: 1999.917 BogoMIPS: 4000.92 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 20480K NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30 NUMA node1 CPU(s): 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31 |
cat /proc/cpuinfo查看每个 CPU 核的信息:
processor : 23 vendor_id : GenuineIntel cpu family : 6 model : 62 model name : Intel(R) Xeon(R) CPU E5-2640 v2 @ 2.00GHz stepping : 4 microcode : 0x416 cpu MHz : 1999.917 cache size : 20480 KB physical id : 1 siblings : 16 core id : 3 cpu cores : 8 apicid : 39 initial apicid : 39 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms bogomips : 4000.92 clflush size : 64 cache_alignment : 64 address sizes : 46 bits physical, 48 bits virtual power management: |
系统平均负载升高的原因
系统平均负载:是处于可运行或不可中断状态的平均进程数。
一般来说,系统平均负载升高意味着 CPU 使用率上升。但是他们没有必然联系,CPU 密集型计算任务较多一般系统平均负载会上升,但是如果 IO 密集型任务较多也会导致系统平均负载升高但是此时的 CPU 使用率不一定高,可能很低因为很多进程都处于不可中断状态,等待 CPU 调度也会升高系统平均负载。
所以假如我们系统平均负载很高,但是 CPU 使用率不是很高,则需要考虑是否系统遇到了 IO 瓶颈,应该优化 IO 读写速度。
所以系统是否遇到 CPU 瓶颈需要结合 CPU 使用率,系统瓶颈负载一起查看
stress: 是一个施加系统压力和压力测试系统的工具,我们可以使用stress
工具压测试 CPU,以便方便我们定位和排查 CPU 问题。
stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s
// --cpu 8:8个进程不停的执行sqrt()计算操作
// --io 4:4个进程不同的执行sync()io操作(刷盘)
// --vm 2:2个进程不停的执行malloc()内存申请操作
// --vm-bytes 128M:限制1个执行malloc的进程申请内存大小
uptime:使用uptime
查看此时系统负载:
watch -d uptime
# -d 参数表示高亮显示变化的区域
mpstat:使用mpstat -P ALL 1
则可以查看每一秒的 CPU 每一核变化信息,整体和top
类似,好处是可以把每一秒(自定义)的数据输出方便观察数据的变化,
最终输出平均数据:
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle Average: all 17.75 0.00 0.58 0.09 0.00 0.04 0.00 0.00 0.00 81.54 Average: 0 54.43 0.00 1.01 0.00 0.00 0.51 0.00 0.00 0.00 44.05 Average: 1 31.30 0.00 0.00 0.00 0.00 0.25 0.00 0.00 0.00 68.45 Average: 2 23.16 0.00 1.02 0.00 0.00 0.00 0.00 0.00 0.00 75.83 Average: 3 35.84 0.00 0.75 0.00 0.00 0.00 0.00 0.00 0.00 63.41 Average: 4 30.90 0.00 1.51 0.00 0.00 0.00 0.00 0.00 0.00 67.59 Average: 5 24.75 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 75.00 Average: 6 20.10 0.00 1.53 0.00 0.00 0.00 0.00 0.00 0.00 78.37 Average: 7 36.87 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 62.88 Average: 8 36.09 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 62.91 Average: 9 18.53 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 81.22 Average: 10 23.29 0.00 1.27 1.52 0.00 0.25 0.00 0.00 0.00 73.67 Average: 11 14.68 0.00 1.01 0.00 0.00 0.00 0.00 0.00 0.00 84.30 Average: 12 44.11 0.00 0.50 0.25 0.00 0.00 0.00 0.00 0.00 55.14 Average: 13 18.16 0.00 0.26 0.00 0.00 0.00 0.00 0.00 0.00 81.59 Average: 14 53.27 0.00 0.75 1.01 0.00 0.00 0.00 0.00 0.00 44.97 Average: 15 29.44 0.00 0.51 0.00 0.00 0.00 0.00 0.00 0.00 70.05 Average: 16 4.01 0.00 1.00 0.00 0.00 0.25 0.00 0.00 0.00 94.74 Average: 17 0.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 99.50 Average: 18 4.59 0.00 0.51 0.00 0.00 0.26 0.00 0.00 0.00 94.64 Average: 19 0.75 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 98.75 Average: 20 4.27 0.00 0.50 0.25 0.00 0.00 0.00 0.00 0.00 94.97 Average: 21 0.76 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 98.99 Average: 22 4.03 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 95.72 Average: 23 1.25 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 98.50 Average: 24 7.75 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 91.75 Average: 25 1.25 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 98.25 Average: 26 3.78 0.00 0.76 0.00 0.00 0.25 0.00 0.00 0.00 95.21 Average: 27 5.54 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 93.95 Average: 28 25.63 0.00 0.75 0.00 0.00 0.00 0.00 0.00 0.00 73.62 Average: 29 4.28 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 95.47 Average: 30 4.03 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 95.72 Average: 31 1.26 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 98.74 |
pidstat:使用pidstat -u 1
则是每隔 1 秒输出当前系统进程、CPU 数据:
03:53:24 PM UID PID %usr %system %guest %CPU CPU Command 03:53:25 PM UID PID %usr %system %guest %CPU CPU Command 03:53:26 PM UID PID %usr %system %guest %CPU CPU Command |
我们使用stress -i 1
来模拟 IO 瓶颈问题,即死循环执行 sync 刷盘操作:
uptime:使用uptime
查看此时系统负载:
pidstat -u 1:查看进程和CPU的关系:
查看此时 IO 消耗,但是实际上我们发现这里 CPU 基本都消耗在了 sys 即系统消耗上。
04:04:00 PM UID PID %usr %system %guest %CPU CPU Command 04:04:01 PM UID PID %usr %system %guest %CPU CPU Command Average: UID PID %usr %system %guest %CPU CPU Command |
IO 无法升高的问题:iowait 无法升高的问题,是因为案例中 stress 使用的是 sync()
系统调用,它的作用是刷新缓冲区内存到磁盘中。对于新安装的虚拟机,缓冲区可能比较小,无法产生大的 IO 压力,这样大部分就都是系统调用的消耗了。
所以,你会看到只有系统 CPU 使用率升高。解决方法是使用 stress 的下一代 stress-ng,它支持更丰富的选项,
比如stress-ng -i 1 --hdd 1 --timeout 600
(--hdd 表示读写临时文件)。
进程数过多问题排查
进程数过多这个问题比较特殊,如果系统运行了很多进程超出了 CPU 运行能,就会出现等待 CPU 的进程。使用stress -c 24
来模拟执行 24 个进程(我的 CPU 是 8 核)
uptime:使用uptime
查看此时系统负载:
Every 2.0s: uptime Thu Aug 20 16:24:32 2020 16:24:32 up 352 days, 6:20, 3 users, load average: 19.73, 26.67, 16.67 |
load average 定义
linux系统中的Load对当前CPU工作量的度量。简单的说是进程队列的长度。
Load Average 就是一段时间 (1 分钟、5分钟、15分钟) 内平均 Load 。
通过系统命令"w"查看当前load average情况
load average值的含义
1) 单核处理器
假设我们的系统是单CPU单内核的,把它比喻成是一条单向马路,把CPU任务比作汽车。当车不多的时候,load <1;当车占满整个马路的时候 load=1;当马路都站满了,而且马路外还堆满了汽车的时候,load>1
2) 多核处理器
我们经常会发现服务器Load > 1但是运行仍然不错,那是因为服务器是多核处理器(Multi-core)。
假设我们服务器CPU是2核,那么将意味我们拥有2条马路,我们的Load = 2时,所有马路都跑满车辆。
什么样的Load average值要提高警惕
三种Load值,应该看哪个
通常我们先看15分钟load,如果load很高,再看1分钟和5分钟负载,查看是否有下降趋势。
1分钟负载值 > 1,那么我们不用担心,但是如果15分钟负载都超过1,我们要赶紧看看发生了什么事情。所以我们要根据实际情况查看这三个值。
通过以上问题现象及解决思路可以总结出:
CPU 上下文:CPU 执行每个任务都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮它设置好 CPU 寄存器和程序计数器(Program Counter,PC)包括 CPU 寄存器在内都被称为 CPU 上下文。
CPU 上下文切换:CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。
CPU 上下文切换:分为进程上下文切换、线程上下文切换以及中断上下文切换。
进程上下文切换
从用户态切换到内核态需要通过系统调用来完成,这里就会发生进程上下文切换(特权模式切换),当切换回用户态同样发生上下文切换。
一般每次上下文切换都需要几十纳秒到数微秒的 CPU 时间,如果切换较多还是很容易导致 CPU 时间的浪费在寄存器、内核栈以及虚拟内存等资源的保存和恢复上,这里同样会导致系统平均负载升高。
Linux 为每个 CPU 维护一个就绪队列,将 R 状态进程按照优先级和等待 CPU 时间排序,选择最需要的 CPU 进程执行。这里运行进程就涉及了进程上下文切换的时机:
sleep
。程序状态Status
进程可运行状态为R
,不可中断运行为D
(后续讲解 top 时会详细说明)
线程上下文切换
线程和进程:
所以线程上下文切换包括了 2 种情况:
中断上下文切换
中断处理会打断进程的正常调度和执行,转而调用中断处理程序,响应设备事件。而在打断其他进程时,就需要将进程当前的状态保存下来,这样在中断结束后,进程仍然可以从原来的状态恢复运行。
对同一个 CPU 来说,中断处理比进程拥有更高的优先级,所以中断上下文切换并不会与进程上下文切换同时发生。
由于中断会打断正常进程的调度和执行,所以大部分中断处理程序都短小精悍,以便尽可能快的执行结束。
查看系统上下文切换
vmstat:工具可以查看系统的内存、CPU 上下文切换以及中断次数:
vmstat 1
每隔1秒输出
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- |
cs:则为每秒的上下文切换次数。
in:则为每秒的中断次数。
r:就绪队列长度,正在运行或等待 CPU 的进程。
b:不可中断睡眠状态的进程数,例如正在和硬件交互。
pidstat:使用pidstat -w
选项查看具体进程的上下文切换次数:
pidstat -w -p 12847 1
05:09:42 PM UID PID cswch/s nvcswch/s Command |
其中cswch/s
和nvcswch/s
表示自愿上下文切换和非自愿上下文切换。
自愿上下文切换:是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。
非自愿上下文切换:则是指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换
sysbench: 工具模拟上下文切换问题。
sysbench --threads=64 --time=300 threads run
--threads |
The total number of worker threads to create | 1 |
--events |
Limit for total number of requests. 0 (the default) means no limit | 0 |
--time |
Limit for total execution time in seconds. 0 means no limit | 10 |
r b swpd free buff cache si so bi bo in cs us sy id wa st |
我们可以明显的观察到:
pidstat -w -u -t 1
-w表示查看进程切换信息,-u查看CPU信息,-t查看线程切换信息
09:50:00 PM UID TGID TID %usr %system %guest %CPU CPU Command |
所以我们可以看到大量的sysbench
线程存在很多的上下文切换。
分析 in 中断问题
我们可以查看系统的
watch -d cat /proc/softirqs
以及
watch -d cat /proc/interrupts
来查看系统的软中断和硬中断(内核中断)。我们这里主要观察/proc/interrupts
即可。
妈的超大一屏幕,没看出来个啥
截个图给你们感受下
总结
/proc/interrupts
文件来分析具体的中断类型。除了系统负载、上下文切换信息,最直观的 CPU 问题指标就是 CPU 使用率信息。Linux 通过/proc
虚拟文件系统向用户控件提供系统内部状态信息,其中/proc/stat
则是 CPU 和任务信息统计。
cat /proc/stat | grep cpu
cpu 6418667257 199753 985546439 87112509362 1920168846 62531 58318839 0 0 0 |
这里每一列的含义如下:
这里我们可以使用top
、ps
、pidstat
等工具方便的查询这些数据,可以很方便的看到 CPU 使用率很高的进程,这里我们可以通过这些工具初步定为,但是具体的问题原因还需要其他方法继续查找。
这里我们可以使用perf top
方便查看热点数据,也可以使用perf record
可以将当前数据保存起来方便后续使用perf report
查看。
这里总结一下 CPU 使用率问题及排查思路:
CPU 使用率主要包含以下几个方面:
平均负载
反应了系统的整体负载情况,可以查看过去 1 分钟、过去 5 分钟和过去 15 分钟的平均负载。
上下文切换
上下文切换主要关注 2 项指标:
CPU 缓存命中率
CPU 的访问速度远大于内存访问,这样在 CPU 访问内存时不可避免的要等待内存响应。为了协调 2 者的速度差距出现了 CPU 缓存(多级缓存)。如果 CPU 缓存命中率越高则性能会更好,我们可以使用以下工具查看 CPU 缓存命中率,工具地址、项目地址 perf-tools
|
通过性能指标查工具(CPU 相关)
性能指标 | 工具 | 说明 |
---|---|---|
平均负载 | uptime top |
uptime 简单展示最近一段时间的平均负载 top 展示更多指标 |
CPU 使用率 | vmstat mpstat top sar /proc/stat |
top、vmstat、mpstat 只可以动态查看当前,而 sar 可以查看历史 /proc/stat 是其他性能工具的数据来源 |
进程 CPU 使用率 | top pidstat ps htop atop |
top、ps 可以以排序方式展示进程 CPU、pidstat 不可排序展示 htop、atop 则以不同颜色展示各类数据更直观 |
系统上下文切换 | vmstat | 展示上下文切换此时、运行状态、不可中断状态进程数量 |
进程上下文切换 | pidstat | 展示项很多,包括进程上下文切换信息 |
软中断 | top /proc/softirqs mpstat |
top 可查看软中断 CPU 使用率 /proc/softirqs 和 mpstat 则可以查看每个 CPU 上的累计信息 |
硬中断 | vmstat /proc/interrupts |
vmstat 查看总中断次数信息 /proc/interrupts 查看各种中断在每个 CPU 核心上的累计信息 |
网络 | dstat sar tcpdump |
dstat、sar 较详细的展示出总的网络收发情况 tcpdump 提供动态抓取数据包的能力 |
IO | dstat、sar | 2 者都提供了详细的 IO 整体情况 |
CPU 信息 | /proc/cpuinfo lscpu |
都可以查看 CPU 信息 |
系统分析 | perf execsnoop |
perf 分析各种内核函数调用、热点函数信息 execsnoop 监控短时进程 |
根据工具查性能指标(CPU 相关)
性能工具 | CPU 性能指标 |
---|---|
uptime | 5、10、15 分钟内的平均负载展示 |
top | 平均负载、运行队列、CPU 各项使用率、进程状态和 CPU 使用率 |
htop | top 增强版,以不同颜色区分不同类型进程,展示更直观 |
atop | CPU、内存、磁盘、网络资源全访问监控,十分齐全 |
vmstat | 系统整体 CPU 使用率、上下文切换次数、中断次数,还包括处于运行(r)和不可中断状态(b)的进程数量 |
pidstat | 进程、线程(-t)的每个 CPU 占用信息,中断上下文切换次数 |
/proc/softirqs | 展示每个 CPU 上的软中断类型及次数 |
/proc/inerrupts | 展示每个 CPU 上的硬中断类型及次数 |
ps | 每个进程的状态和 CPU 使用率 |
pstree | 进程的父子关系展示 |
dstat | 系统整体 CPU 使用率(以及相关 IO、网络信息) |
sar | 系统整体 CPU 使用率,以及使用率历史信息 |
strace | 跟踪进程的系统调用 |
perf | CPU 性能事件分析,例如:函数调用链、CPU 缓存命中率、CPU 调度等 |
execsnoop | 短时进程分析 |
CPU 问题排查方向
有了以上性能工具,在实际遇到问题时我们并不可能全部性能工具跑一遍,这样效率也太低了,所以这里可以先运行几个常用的工具 top、vmstat、pidstat 分析系统大概的运行情况然后在具体定位原因。
top 系统CPU => vmstat 上下文切换次数 => pidstat 非自愿上下文切换次数 => 各类进程分析工具(perf strace ps execsnoop pstack)
top 用户CPU => pidstat 用户CPU => 一般是CPU计算型任务
top 僵尸进程 => 各类进程分析工具(perf strace ps execsnoop pstack)
top 平均负载 => vmstat 运行状态进程数 => pidstat 用户CPU => 各类进程分析工具(perf strace ps execsnoop pstack)
top 等待IO CPU => vmstat 不可中断状态进程数 => IO分析工具(dstat、sar -d)
top 硬中断 => vmstat 中断次数 => 查看具体中断类型(/proc/interrupts)
top 软中断 => 查看具体中断类型(/proc/softirqs) => 网络分析工具(sar -n、tcpdump) 或者 SCHED(pidstat 非自愿上下文切换)
CPU 问题优化方向
性能优化往往是多方面的,CPU、内存、网络等都是有关联的,这里暂且给出 CPU 优化的思路,以供参考。
程序优化
gcc -O2
对程序代码优化。nlogn
的排序算法,使用logn
的查找算法等。系统优化
sysbench安装:https://github.com/akopytov/sysbench#debianubuntu
CPU参数模拟:https://mp.weixin.qq.com/s/7HGjAy_R_sdpfckFlFr0cw
load average参数:https://www.cnblogs.com/kaituorensheng/p/3602805.html