1. Linux操作系统CPU平均负载
以前我们总认为CPU使用率和CPU平均负载是一样的,负载高了就是CPU使用率提高。但是到底是什么情况呢?
1.1. CPU的平均负载
单位时间内 系统处于 可运行状态 和不可中断状态 的平均进程数,就是平均活跃进程数,和CPU使用率并没有直接关系
- 可运行状态:
-
- 正在使用CPU或者等待CPU的进程
- 用ps aux命令看到的, 处于R状态(Running或Runnable)的进程
- 不可中断状态:
-
- 正处于内核态关键流程中的进程,且流程不可被打断。
- 比如 等待硬件设备的IO响应,为了保证数据一致性,进程向磁盘读写数据时,在得到磁盘响应前是不能被其他进程中断打断的
- ps aux 命令中D状态的进程
PS 中常见 STAT 状态 | 描述 |
D | 无法中断的休眠状态(通常 IO 的进程) |
R | 正在运行,或在队列中的进程 |
S | 处于休眠状态 |
T | 停止或被追踪 |
Z | 僵尸进程 |
< | 优先级高的进程 |
n | 优先级较低的进程 |
L | 有些页被锁进内存 |
s | 进程的领导者(在它之下有子进程) |
l | 多进程的(使用 CLONE_THREAD,类似 NPTL pthreads) |
+ | 位于后台的进程组 |
1.2. 如何查看平均负载?
我们可以使用uptime
查询CPU的平均负载。
load average后的3个数字分别代表1分钟,5分钟,15分钟的CPU平均负载。
查看服务器总的逻辑cpu个数:cat /proc/cpuinfo | grep "processor" | wc -l
分析:
- 如果我们的平均负载为2,则逻辑cpu为2时刚刚好可以利用。但是如果逻辑cpu为4,则表示有50%空闲
- 如果1,5,15分钟差值不大,说明负载稳定。
- 如果1分钟值远小于15分钟,说明系统最近1分钟在降低,前15分钟压力大;如果1分钟值远大于15分钟,则表示最近1分钟的负载在增加,平均负载接近或超越CPU个数,意味着系统正在发生过载问题,持续的时间长说明问题需要优化。
平均负载的合理分布范围:常规推荐等于CPU核数即可,同时也要看业务场景和历史趋势。
2. CPU的使用率和平均负载区别
2.1. CPU使用率
CPU非空闲状态运行的时间占比,反映CPU的繁忙程度,和平均负载不一定完全一致。
比如当我们在进行软件开发的时候,我们项目前期每个人都有比较多的事情去做,这时候平均负载很高,CPU使用率也很高。当项目进入测试阶段,开发人员都在等待测试结果,十分空闲却不可以离开现在的岗位,这时候的CPU利用率很低但是负载很高。
在生产中系统的CPU使用总量不建议超过70%~80%。
Linux中我们使用top
命令来查看CPU的使用率
- us(user):CPU 在用户态运行的时间百分比,通常用户态 CPU 高表示有应用程序比较繁忙,值高则 CPU 使用率高。
- sy(sys):CPU 在内核态运行的时间百分比(不包括中断),内核态 CPU 越低越不值,值高则 CPU 使用率高。
- id(idle):CPU 处于空闲态的时间占比,CPU 会执行一个特定的虚拟进程,名为 System Idle Process,值高的话,说明 CPU 比较空闲。
- wa(iowait):CPU 在等待 I/O 操作完成所消耗的时间,该指标越低越好,否则表示 I/O 存在瓶颈,用 iostat 命令进一步分析。
- hi(hardirq):CPU 处理硬中断所花费的时间,由外设硬件(如键盘控制器、硬件传感器等)发出的中断信号,快速执行。
- si(softirq):CPU 处理软中断所花费的时间,由软件程序(如网络收发、定时调度等)发出的中断信号,延迟执行。
- st(steal):CPU 被其他虚拟机占用的时间,仅出现在多虚拟机场景,指标过高的话,检查下宿主机或其他虚拟机是否异常。
2.2. CPU使用率和平均负载的区别
CPU平均负载 指单位时间内活跃进程数,包括正在使用CPU的进程,还包括可等待CPU和等待IO的进程(不可中断状态)。
CPU使用率 是指单位时间内CPU繁忙情况的统计。
- CPU密集型:也叫做计算机密集型,表示该任务需要大量的运算,没有阻塞CPU一直会全速运行。
- IO密集型: 程序需要大量IO操作,大部分时间是CPU在等待IO(硬盘/内存)的读写操作。CPU使用率低,但等待IO也会导致平均负载升高。当线程进行IO操作CPU空闲时,启动其他线程继续使用CPU,提高CPU的使用率。
区别说明:
- CPU密集型进程,使用大量CPU运算 会导致平均负载升高,这个场景两者是一致的
- IO密集型进程,等待IO也会导致平均负载升高,但CPU使用率不一定高
-
- CPU的效率要远高于磁盘,磁盘读写请求过多会导致大量IO等待
- 进程在CPU上访问磁盘文件,CPU会像内核发起调用文件请求,让内核去取磁盘文件,这个时候CPU会切换到其他进程或者空闲
- 任务会转换为 不可中断的睡眠状态,当这种读写请求过多会导致不可中断睡眠状态的进程过多,导致CPU负载高,利用率低的情况。
- 大量等待CPU的进程调度也会导致平均负载升高,此时CPU使用率也会比较高
3. 生成环境Linux操作系统CPU压测环境准备
我们知道线上Linux会存在多个瓶颈问题,CPU、内存、IO、带宽等,所以这时候我们就需要去准备相应的工具,模拟生成环境出现的多种问题,这时候我们选择的压测程序,让CPU产生瓶颈,如何再进行分析。
目标:分析Linux相关性能指标,找出CPU平均负载升高的进程和原因,原因一般为多个进程抢占CPU、等待IO、CPU上下文切换
思路:先看全局,找到系统的哪个资源问题,是CPU还是IO还是啥瓶颈,。知道具体后,再看啥哪个进程导致的这个资源问题。
核心命令+应用场景:
- sysstat 工具包的命令
-
- mpstat(全局) 多核CPU性能分析程序,实时查看每个CPU的性能指标和全局CPU的平均性能指标
- pidstat(局部) 实时查看进程的CPU、内存、IO、上下文切换等指标
- vastart(全局)实时查看系统的上下文切换(跨进程间,同个进程里多个子进程)、系统中断次数
下载地址:https://mirrors.aliyun.com/blfs/conglomeration/sysstat/ 版本号为:12.7.2
在 /user/local/software/arch文件夹下传入sysstat压缩包,编写以下指令
# 安装环境
yum install unzip -y# 进入目录
cd /user/local/software/arch# 解压缩文件
tar -xvJf sysstat-12.7.2.tar.xz# 配置编译参数
./configure# 编译并安装
make
sudo make install# 查看版本
pidstat -V
模拟压测工具:
- stress多进程工具,模拟IO密集型应用,CPU密集型应用,多进程等待CPU调度场景,对CPU,内存,IO等情况进程压测
yum install -y epel-release
yum install stress -y
- sysbench多线程基准测试工具,模拟上下文切换过多场景等
sudo yum install -y epel-release
sudo yum install -y sysbench
sysbench --version
基准测试:
- 通过设计科学的测试方法、测试工具和测试系统,实现对一类测试对象的某项性能指标进行定量的和看对比的测试
- 技术人员为了确定当前环境、系统、服务器等的性能情况而进行的测试,为了在同一环境条件下进行性能优而进行的测试
- 场景:数据库sql语句、索引、应用代码、网络、机器硬件配置等
- 核心点
-
- 测试过程是看重复执行的
- 每次的基准测试都应该在相同环境下进行,除了某项测试变动,其他的软件和硬件组成等各种保持一致
- 除了被测试系统是处于运行和可调整状态外,要避免其他程序或者调整,以免影响基准测试结果
4. Linux性能优化诊断pidstat+mpstat
4.1. mpstat
多核CPU性能分析程序,实时查看每个CPU的性能指标和全部CPU的平均性能指标。
- 使用场景:当系统变慢,CPU平均负载增大,判断是CPU的使用率增大,还是IO压力增大的情况导致
- 格式:
mpstat [-P {ALL|n}] [ <时间间隔> ] [ <次数> ]
列如:mpstat -P ALL 2 3
,表示每隔2秒出一个报告数据,共出3次
参数 | 说明 |
-P | 指定监控哪个 CPU,范围是 [0 - (N-1)],ALL 表示监控所有 CPU 都监控 |
internal | 两次采样的间隔时间 |
count | 总采样次数 |
字段 | 说明 |
CPU | 全部 CPU 和某个 CPU,从 0 开始 |
%usr | 用户态所使用 CPU 时间的百分比,CPU 使用率 |
%nice | nice 值为负进程的 CPU 时间,即使用 nice 命令对进程进行降级时 CPU 的百分比 |
%sys | 内核态所使用 CPU 时间的百分比,CPU 使用率 |
%iowait | CPU 在等待 I/O 操作完成所消耗的时间,高表示可能 I/O 存在瓶颈 |
%irq | 用于硬中断的 CPU 百分比 |
%soft | 用于软中断的 CPU 百分比 |
%steal | 虚拟机强制 CPU 等待的时间百分比(基本很少关注) |
%guest | 虚拟机占用 CPU 时间的百分比(基本很少关注) |
%gnice | CPU 运行带 nice guest 虚拟机所花费的时间百分比(基本很少关注) |
%idle | CPU 空闲且系统没有未完成的磁盘 I/O 请求的时间百分比;CPU 使用率低,iowait 高,idle 低的话可能是等待 I/O |
4.2. pidstat
实时查看进程的CPU、内存、IO、上下文切换等指标
- 格式:
pidstat [ 选项 ] [ <时间间隔> ] [ <次数> ]
,比如pidstat -u 2 3
表示每隔 2 秒出一个报告数据,一共出具 3 次。 - 输出排序:
pidstat -u | sort -k 8 -r
-
sort
排序:指定排序用哪一列,示例中是第 8 列%CPU
。-r
:倒序。
参数 | 说明 |
-u | 默认的参数,显示各个进程的 cpu 使用统计,监控 cpu, 和 是等效的 |
-r | 显示各个进程的内存使用统计,监控内存 |
-d | 显示各个进程的 I/O 使用情况,监控硬盘 |
-p | 指定进程号,比如 |
-w | 显示每个进程的上下文切换情况 |
-t | 显示选择任务的线程的统计信息外的额外信息 |
字段 | 说明 |
PID | 进程 ID |
%usr | 进程在用户态所使用 CPU 时间的百分比,CPU 使用率 |
%system | 进程在内核态所使用 CPU 时间的百分比,CPU 使用率 |
%guest | 进程在虚拟机占用 cpu 的百分比(基本很少关注) |
%wait | 进程等待 cpu 的时间百分比,进程处于就绪队列中的状态等待 CPU 调度运行的百分比【新版才有】 |
%CPU | 进程占用 cpu 的百分比,和 top 命令一样等于用户态 CPU + 内核态 CPU,如果要区分 cpu 哪个多则用 pidstat |
CPU | 处理进程的 cpu 编号 |
Command | 当前进程对应的命令 |
pidstat -d
字段 | 说明 |
PID | 进程 ID |
kB_rd/s | 每秒从磁盘读取的 KB |
kB_wr/s | 每秒写入磁盘 KB |
kB_ccwr/s | 每秒进程被取消向磁盘写的数据量 (以 kB 为单位) |
iodelay | 块 I/O 延迟(iodelay),包括等待同步块 I/O 和换入块 I/O 结束的时间 |
Command | 当前进程对应的命令 |
4.3. 压测工具stress
多线程工具,模拟IO密集型应用,CPU密集型应用,多线程等待CPU调度场景,对CPU,内存,IO等情况进行压测
参数 | 说明 |
--timeout | 指定运行多少秒 |
--cpu N | 产生多个处理 函数的 CPU 进程,每个进程高频的计算随机数的平方根,模拟 CPU 计算密集型场景 |
--io N | 产生多个处理 函数的磁盘 I/O 进程,每个进程高频调用 ,刷内存缓冲区到磁盘,模拟 I/O 密集型场景 |
--vm N | 每个进程高频调用内存分配 和内存释放 函数 |
--vm-bytes | 指定 时申请内存的字节数,默认 256MB |
--hdd N | 产生 N 个高频执行 和 函数的进程(创建 / 写入 / 删除文件),属于磁盘 I/O 进程 |
--hdd-bytes | 每个 hdd worker 进程读写的 byte 数,默认 1G |
5. 综合实战
5.1. 模拟 CPU 密集型应用,系统是 4 核
- 终端一:模拟两个 CPU 核的使用率 100%,对 2 个 CPU 进行压力测试,持续 600s,命令为
stress --cpu 2 --timeout 600
- 终端二:
-d
参数表示高亮显示变化的区域,命令为watch -d uptime
- 终端三:
mpstat
查看 CPU 使用率情况,每 5 秒监控所有 CPU 情况,命令为mpstat -P ALL 5
- 终端四:查看运行中的进程和任务,每 5 秒刷新一次,命令为
pidstat -u 5
宏观思路
- 先看全局,找系统哪个资源有问题,是 CPU、I/O 还是磁盘瓶颈
- 知道具体问题后,再看是哪个进程导致的这个资源问题
详细分析思路
- 全局
-
uptime
:运行 1 分钟后,4 个核的 CPU 负载是 2,高负载可以到 4mpstat
:
-
-
- 应用场景:当系统变慢,CPU 平均负载增大时,判断是 CPU 的使用率增大,还是 I/O 压力增大的情况导致
- CPU 的两个核在用户态使用率是 100%,两个核数空闲的,总的 CPU 使用率是 50%,% iowait 为 0,不存在 I/O 瓶颈
sqrt()
函数的 CPU 进程是在用户态,所以是 % usr 升高,而 % sys 没啥变化
-
- 局部
-
pidstat
:对进程和任务的使用情况进行查看,发现stress
进程对 2 块 CPU 使用率过高,导致 CPU 平均负载增加。- 举一反三:如果不是
stress
,其他进程造成这类影响的,靠这个思路也能排查出是哪个进程,包括压测 4 个核。 - CPU 使用率高,CPU 平均负载也高;CPU 平均负载高,CPU 使用率不一定高。
线程1
线程2
线程3
线程4
5.2. 模拟 I/O 密集型应用,系统是 4 核
- 终端一:模拟四个 I/O 进程,持续 600s,命令为
stress --io 4 --timeout 600
- 终端二:
-d
参数表示高亮显示变化的区域,命令为watch -d uptime
- 终端三:
mpstat
查看 CPU 使用率情况,每 5 秒监控所有 CPU 情况,命令为mpstat -P ALL 5
- 终端四:查看运行中的进程和任务,每 5 秒刷新一次,命令为
pidstat -u 5
- 宏观思路
-
- 先看全局,找系统哪个资源有问题,是 CPU、I/O 还是磁盘瓶颈
- 知道具体问题后,再看是哪个进程导致的这个资源问题
- 局部
-
pidstat
:对进程和任务的使用情况进行查看,发现stress
进程对 CPU 使用率比较高,导致 CPU 平均负载增加- % iowait 有一定数值,但不高,使用
pidstat -d
查看,没太多磁盘读写,但有 iodelay
线程一
线程二
线程三
线程四
5.3. IO密集型案例
- 终端一:模拟两个磁盘 I/O 进程,持续 600s,命令为
stress --hdd 2 --hdd-bytes 6G --timeout 600
- 终端二:
-d
参数表示高亮显示变化的区域,命令为watch -d uptime
- 终端三:
mpstat
查看 CPU 使用率情况,每 5 秒监控所有 CPU 情况,命令为mpstat -P ALL 2 3
(每隔 2 秒出一个报告数据,一共出具 3 次) - 终端四:查看运行中的进程和任务,每 5 秒刷新一次,命令为
pidstat -u 2 3
(每隔 2 秒出一个报告数据,一共出具 3 次)
宏观思路
- 先看全局,找系统哪个资源有问题,是 CPU、I/O 还是磁盘瓶颈。
- 知道具体问题后,再看是哪个进程导致的这个资源问题。
详细分析思路
- 全局
-
uptime
:运行 1 分钟后,4 个核的 CPU 负载比较高。mpstat
:
-
-
- 应用场景:当系统变慢,CPU 平均负载增大时,判断是 CPU 的使用率增大,还是 I/O 压力增大的情况导致
- 多次调用
mpstat
,持续观察,平均负载升高,但 CPU 使用率没啥变化,% iowait 大于 50% 且比较高 - 一直在等待 I/O 处理,说明进程是 I/O 密集型,进程频繁进行 I/O 操作,导致系统平均负载很高,而 CPU 使用率不高
-
- 局部
-
ps aux
里stat
字段 D 的状态一般是 I/O 出现了问题,说明进程在等待 I/O,比如磁盘 I/O、网络 I/O 或者其他pidstat
:对进程和任务的使用情况进行查看,发现stress
进程对 CPU 使用率不高,但 CPU 平均负载高- 举一反三:如果不是
stress
,其他进程造成这类影响的,靠这个思路也能排查出是哪个进程。 - CPU 使用率高,CPU 平均负载也高;CPU 平均负载高,CPU 使用率不一定高,则可能 I/O 瓶颈
线程一
线程二
线程三
线程三
5.4. 大量等待 CPU 的进程调度,导致平均负载升高,CPU 使用率也会比较高,系统是 4 核
- 终端一:模拟 8 个进程(也可更多),持续 600s,命令为
stress --cpu 8 --timeout 600
- 终端二:
-d
参数表示高亮显示变化的区域,命令为watch -d uptime
- 终端三:
mpstat
查看 CPU 使用率情况,每隔 2 秒出一个报告数据,一共出具 3 次,命令为mpstat -P ALL 2 3
- 终端四:查看运行中的进程和任务,每隔 2 秒出一个报告数据,一共出具 3 次,命令为
pidstat -u 2 3
宏观思路
- 先看全局,找系统哪个资源有问题,是 CPU、I/O 还是磁盘瓶颈。
- 知道具体问题后,再看是哪个进程导致的这个资源问题。
详细分析思路
- 全局
-
uptime
:运行 1 分钟后,4 个核的 CPU 负载比较高。mpstat
:
-
-
- 应用场景:当系统变慢,CPU 平均负载增大时,判断是 CPU 的使用率增大,还是 I/O 压力增大的情况导致
- 多次调用
mpstat
,持续观察,平均负载升高,每个 CPU 利用率都高,使用率接近 100%,% iowait 很低接近 0,I/O 不是瓶颈 - 再进一步分析,CPU 利用率高,主要是哪部分操作占据了 CPU
-
- 局部
-
pidstat
:对进程和任务的使用情况进行查看,发现%wait
高,说明 CPU 不够用,在等待 CPU 调度上花费了不少时间- 结论:8 个进程在竞争 4 个 CPU,每个进程等待 CPU 的时间达到 50%(
%wait
),超出 CPU 计算能力的进程,导致了负载变高
-
-
pidstat -u
:CPU 情况,默认pidstat -d
:磁盘 I/O 情况,基本很低
-
-
- 举一反三:如果不是
stress
,其他进程造成这类影响的,靠这个思路也能排查出是哪个进程
- 举一反三:如果不是
线程一
线程二
线程三
线程四