操作系统-cpu部分-工具使用-寻找平均负载升高的原因-查询系统的上下文切换情况-系统iowait 升高的原因

目标:寻找平均负载升高的原因

现在大多数CPU有超线程能力,在计算和评估平均负载的时候,CPU的核数是指物理核数,还是超线程功能的逻辑核数?
关于平均负载多少合理中,理想情况下等于cpu核数的描述,这里的cpu核数值得是逻辑核数
在这里插入图片描述

演示环境介绍:
操作系统:ubuntu18.04
机器配置:4 CPU,4GB 内存。
预先安装 stress 和 sysstat 包,如 apt install stress sysstat。

工具介绍
在这里,我先简单介绍一下 stress 和 sysstat。

压力测试工具stress

stress 是一个 Linux 系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场
景。

性能分析工具mpstat和pidstat

而 sysstat 包含了常用的 Linux 性能工具,用来监控和分析系统的性能。我们的案例会用到
这个包的两个命令 mpstat 和 pidstat。

mpstat 是一个常用的多核 CPU 性能分析工具,用来实时**查看每个 CPU 的性能指标,以及所有 CPU 的平均指标。**
pidstat 是一个常用的**进程性能分析工具**,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。

场景一:CPU 密集型进程

在第一个终端运行 stress 命令,模拟一个 CPU 使用率 100% 的场景
$ stress --cpu 1 --timeout 600

在第二个终端运行 uptime 查看平均负载的变化情况:
#-d 参数表示高亮显示变化的区域
$ watch -d uptime
在这里插入图片描述

在第三个终端运行 mpstat 查看 CPU 使用率的变化情况
-P ALL 表示监控所有 CPU,后面数字 5 表示间隔 5 秒后输出一组数据
$ mpstat -P ALL 5
在这里插入图片描述
在这里插入图片描述

那么,到底是哪个进程导致了 CPU 使用率为 100% 呢?你可以使用 pidstat 来查询:

间隔 5 秒后输出一组数据
$ pidstat -u 5 1
在这里插入图片描述

场景二:I/O密集型进程

运行 stress 命令,但这次模拟 I/O 压力,即不停地执行 sync
stress -i 1 --timeout 600

场景三:大量进程的场景

当系统中运行进程超出 CPU 运行能力时,就会出现等待 CPU 的进程。
使用 stress,但这次模拟的是 8 个进程:
stress -c 8 --timeout 600

htop工具

用htop看负载,因为它更直接(在F2配置中勾选所有开关项,打开颜色区分功
能),不同的负载会用不同的颜色标识。比如cpu密集型的应用,它的负载颜色是绿色偏
高,iowait的操作,它的负载颜色是红色偏高等等,根据这些指标再用htop的sort就很容
易定位到有问题的进程。

htop是一个功能强大且用户友好的系统进程监控工具,它是传统top命令的升级版。

以下是一些htop的主要特点和优势:

实时监控:它可以实时显示系统的资源使用情况,包括CPU、内存、磁盘IO和网络等信息。
用户界面:htop提供了一个彩色的界面,以直观的方式展示信息,使得查看和管理进程更加方便。
交互操作:支持鼠标和键盘交互操作,可以方便地进行排序、过滤和查找等操作。这允许用户通过鼠标点击来kill进程而无需输入PID。
功能丰富:htop提供了诸如进程树视图、进程优先级设置和进程终止等丰富的功能。
快速启动:相比传统的top命令,htop启动更快,不需要像top那样在显示任何内容之前收集一段时间的数据。
操作简便:在htop中,用户无需输入进程编号或优先级值来重新分配进程,还可以同时杀死多个进程。
总的来说,htop是Linux系统管理员和用户监控和管理系统进程的有力工具,它通过提供一个直观、易用和功能丰富的界面,帮助用户更有效地管理和监控他们的系统【来自讯飞星火大模型的工具介绍】
在这里插入图片描述
在这里插入图片描述

atop工具

还有个更好用的atop命令,好像是基于sar的统计生成的报告,直
接就把有问题的进程标红了,更直观。

atop是一款功能全面的Linux服务器监控工具,专门用于监控系统资源和进程。具体介绍如下:

数据采集:atop能够详细地采集包括CPU、内存、磁盘、网络在内的系统资源使用情况,以及所有进程使用这些资源的情况。
数据展示:它通过特殊的颜色展示系统的压力情况,如红色表示情况严重,这有助于用户快速识别问题所在。
日志记录:atop可以定期采集相关数据并保存在日志文件中,用户可以通过调整atop.daily文件来设置数据采集的间隔和日志文件的保存时间。
性能监控:作为一个基于ASCII的全屏性能监控工具,atop还能高亮显示出过载的进程,帮助用户关注系统的活动时间和负载情况。
总的来说,atop是一个适合Linux系统管理员使用的监控工具,它不仅提供了丰富的系统监控数据,还能够通过日志记录和性能分析帮助用户了解系统的运行状态,从而更好地进行系统管理和优化。【来自讯飞星火大模型的工具介绍】
在这里插入图片描述

lsof工具

lsof(list open files)是一款用于显示当前系统打开文件的工具

以下是一些关于lsof的详细介绍:

功能丰富:lsof可以列出当前系统中进程打开的所有文件,包括网络套接口等一切皆文件的对象。它能够显示普通文件、目录、特殊的块设备文件、管道、套接字(socket)、设备以及Unix域套接字等信息。
监控诊断:作为一款系统监控和系统诊断工具,lsof在实际使用中非常强大。例如,可以用它来检测哪个进程在使用某个特定的文件或者端口,从而帮助解决文件占用或者网络连接问题。
命令选项:lsof提供了丰富的命令行选项以供用户选择。这些选项包括但不限于-h(显示帮助信息)、-a(满足多个条件时才显示结果)、-R(显示进程的PPID列)、-l(不将UID转化为用户名)、-n(不将IP转换为主机名)、-P(不将服务端口号转化为服务名称)和-u(指定Username或UID)等。
安装与使用:lsof命令可能需要安装后才能使用,可以通过如yum install -y lsof这样的命令进行安装。由于需要访问核心内存和各种文件,通常建议以root用户身份运行lsof以发挥其全部功能。
总的来说,lsof是一个在Linux系统管理、监测和故障排除中不可或缺的工具,它能够帮助系统管理员快速定位和解决各种与文件及进程相关的问题。

在使用lsof命令时,以下是一些常见的使用案例

查看特定进程打开的文件:lsof -p pid,其中pid是你想要查看的进程ID。这会列出该进程所有已打开的文件
简化输出内容:lsof -l,这将使用文件描述符(FD)号码代替进程名,使输出更加简洁。
查找用户相关的打开文件:lsof -u userName,通过指定用户名来过滤出该用户打开的所有文件。
搜索包含特定关键字的进程:lsof -c string,这会查找COMMAND列中包含特定字符串的进程。
恢复被删除的文件:有时,即使文件已被删除,某些进程可能仍然保持该文件打开。使用lsof可以找出这些仍保持文件打开的进程,有助于恢复或重新获得对这些文件的访问。
查看网络连接和套接字:由于在Linux中,许多事物都是以文件形式存在,包括网络连接和硬件设备。使用lsof可以显示当前系统打开的网络连接和套接字等信息。
此外,lsof还有许多其他选项和参数,例如-a用于满足多个条件时才显示结果,-R用于显示进程的PPID列等。具体使用时,可以根据需要组合不同的参数以满足特定的监控或排错需求。

总的来说,lsof是一个功能非常强大的工具,对于系统管理员来说,掌握它能够帮助有效地进行系统监控、性能分析以及故障排查。在使用lsof时,建议结合具体的使用场景和目标,选择适当的参数和命令来达到最佳的效果。
在这里插入图片描述

目标:查询系统的上下文切换情况

vmstat工具-系统总体上下文切换情况

vmstat 是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分
析 CPU 上下文切换和中断的次数。
在这里插入图片描述

我们一起来看这个结果,你可以先试着自己解读每列的含义。在这里,我重点强调下,需要
特别关注的四列内容
在这里插入图片描述

cs(context switch)是每秒上下文切换的次数。
in(interrupt)则是每秒中断的次数。
r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程
数。
b(Blocked)则是处于不可中断睡眠状态的进程数。

vmstat 只给出了系统总体的上下文切换情况,要想查看每个进程的详细情况,就需要使用
我们前面提到过的 pidstat 了。给它加上 -w 选项,你就可以查看每个进程上下文切换的情
了。

pidstat工具加w选项–每个进程上下文切换的情况

在这里插入图片描述

这个结果中有两列内容是我们的重点关注对象。一个是 cswch ,表示每秒自愿上下文切换
(voluntary context switches)的次数,另一个则是 nvcswch ,表示每秒非自愿上下文
切换
(non voluntary context switches)的次数。
这两个概念你一定要牢牢记住,因为它们意味着不同的性能问题:

所谓自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、
内存等系统资源不足时,就会发生自愿上下文切换。

非自愿上下文切换,则是指进程由于时间片已到等原因,被系统强制调度,进而发生的
上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换。

sysbench工具–模拟系统多线程调度切换的情况

使用 sysbench 来模拟系统多线程调度切换的情况。
sysbench 是一个多线程的基准测试工具,一般用来评估不同系统参数下的数据库负载情
况。当然,在这次案例中,我们只把它当成一个异常进程来看,作用是模拟上下文切换过多
的问题。

预先安装 sysbench 和 sysstat 包,如 apt install sysbench sysstat

案例:模拟系统多线程调度切换

实验步骤
首先,在第一个终端里运行 sysbench ,模拟系统多线程调度的瓶颈:
以 10 个线程运行 5 分钟的基准测试,模拟多线程切换的问题
$ sysbench --threads=10 --max-time=300 threads run

在这里插入图片描述

接着,在第二个终端运行 vmstat ,观察上下文切换情况
#每隔 1 秒输出 1 组数据(需要 Ctrl+C 才结束)
$ vmstat 1
在这里插入图片描述
在这里插入图片描述

你应该可以发现,cs 列的上下文切换次数从之前的 35 骤然上升到了 139 万。同时,注意
观察其他几个指标:

r 列:就绪队列的长度已经到了 8,远远超过了系统 CPU 的个数 2,所以肯定会有大量
的 CPU 竞争。
us(user)和 sy(system)列:这两列的 CPU 使用率加起来上升到了 100%,其中系
统 CPU 使用率,也就是 sy 列高达 84%(黑色图片数据分析65%),说明 CPU 主要是被内核占用了。
in 列:中断次数也上升到了 1 万左右,说明中断处理也是个潜在的问题。

那么到底是什么进程导致了这些问题呢?

我们继续分析,在第三个终端再用 pidstat 来看一下, CPU 和进程上下文切换的情况:
#每隔 1 秒输出 1 组数据(需要 Ctrl+C 才结束)
#-w 参数表示输出进程切换指标,而 -u 参数则表示输出 CPU 使用指标
$ pidstat -wu 1
在这里插入图片描述

从 pidstat 的输出你可以发现,CPU 使用率的升高果然是 sysbench 导致的,它的 CPU 使
用率已经达到了 100%。但上下文切换则是来自其他进程,包括非自愿上下文切换频率最高
的 pidstat ,以及自愿上下文切换频率最高的内核线程 kworker 和 sshd。

pidstat 输出的上下文切换次数,加起来也
就几百,比 vmstat 的 139 万明显小了太多。这是怎么回事呢?难道是工具本身出了错
吗?
别着急,在怀疑工具之前,我们再来回想一下,前面讲到的几种上下文切换场景。其中有一
点提到, Linux 调度的基本单位实际上是线程,而我们的场景 sysbench 模拟的也是线程
的调度问题,那么,是不是 pidstat 忽略了线程的数据呢?
通过运行 man pidstat ,你会发现,pidstat 默认显示进程(process)的指标数据,加上 -t 参数后,
才会输出线程(threads)的指标。
在这里插入图片描述
在这里插入图片描述

所以,我们可以在第三个终端里, Ctrl+C 停止刚才的 pidstat 命令,再加上 -t 参数,重试
一下看看:

#每隔 1 秒输出一组数据(需要 Ctrl+C 才结束)
#-wt 参数表示输出线程的上下文切换指标
在这里插入图片描述
在这里插入图片描述

前面在观察系统指标时,除了上下文切换频率骤然升高,
还有一个指标也有很大的变化。是的,正是中断次数。中断次数也上升到了 1 万,但到底
是什么类型的中断上升了,现在还不清楚。我们接下来继续抽丝剥茧找源头。
既然是中断,我们都知道,它只发生在内核态,而 pidstat 只是一个进程的性能分析工具,
并不提供任何关于中断的详细信息,怎样才能知道中断发生的类型呢?
没错,那就是从 /proc/interrupts 这个只读文件中读取。/proc 实际上是 Linux 的一个虚
拟文件系统,用于内核空间与用户空间之间的通信。/proc/interrupts 就是这种通信机制的
一部分,提供了一个只读的中断使用情况。

#-d 参数表示高亮显示变化的区域
$ watch -d cat /proc/interrupts

观察一段时间,你可以发现,变化速度最快的是重调度中断(RES),这个中断类型表示,
唤醒空闲状态的 CPU 来调度新的任务运行。这是多处理器系统(SMP)中,调度器用来分
散任务到不同 CPU 的机制,通常也被称为处理器间中断(Inter-Processor Interrupts,IPI)。

所以,这里的中断升高还是因为过多任务的调度问题,跟前面上下文切换次数的分析结果是一致的。

每秒上下文切换多少次才算正常呢?(小结)

这个数值其实取决于系统本身的 CPU 性能。在我看来,如果系统的上下文切换次数比较稳定,那么从数百到一万以内,都应该算是正常的。但当上下文切换次数超过一万次,或者切换次数出现数量级的增长时,就很可能已经出现了性能问题。

这时,你还需要根据上下文切换的类型,再做具体分析。比方说:

自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题;
非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU的确成了瓶颈
中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型。

目标:查询系统iowait 升高的原因

一提到 iowait 升高,你首先会想要查询系统的 I/O 情况。我一般也是这种思路,
那么什么工具可以查询系统的 I/O 情况呢?

性能监控工具-dstat

我推荐的是 dstat ,它的好处是,可以同时查看 CPU 和 I/O 这两种资源的使用情况,便于对比分析。

dstat 是一个新的性能工具,它吸收了 vmstat、iostat、ifstat 等几种工具的优点,
可以同时观察系统的 CPU、磁盘 I/O、网络以及内存使用情况。
在这里插入图片描述

在终端中运行 dstat 命令,观察 CPU 和 I/O 的使用情况

#间隔 1 秒输出 10 组数据
$ dstat 1 10
在这里插入图片描述
在这里插入图片描述
从 dstat 的输出,我们可以看到,每当 iowait 升高(wai)时,磁盘的读请求(read)都
会很大。这说明 iowait 的升高跟磁盘的读请求有关,很可能就是磁盘读导致的。
(观察白色第8/11/13行,wai为100,对应read为34M)

我们从 top 的输出找到 D 状态进程的 PID,你可以发现,这个界面里有两个 D 状态的进
程,PID 分别是 4344 和 4345。
接着,我们查看这些进程的磁盘读写情况。对了,别忘了工具是什么。一般要查看某一个进
程的资源使用情况,都可以用我们的老朋友 pidstat,不过这次记得加上 -d 参数,以便输
出 I/O 使用情况。
比如,以 4344 为例,我们在终端里运行下面的 pidstat 命令,并用 -p 4344 参数指定进
程号:
#-d 展示 I/O 统计数据,-p 指定进程号,间隔 1 秒输出 3 组数据
$ pidstat -d -p 4344 1 3
在这里插入图片描述

在这个输出中, kB_rd 表示每秒读的 KB 数, kB_wr 表示每秒写的 KB 数,iodelay 表示
I/O 的延迟(单位是时钟周期)。它们都是 0,那就表示此时没有任何的读写,说明问题不
是 4344 进程导致的。

那要怎么知道,到底是哪个进程在进行磁盘读写呢?我们继续使用 pidstat,但这次去掉进
程号,干脆就来观察所有进程的 I/O 使用情况
在终端中运行下面的 pidstat 命令:

#间隔 1 秒输出多组数据 (这里是 20 组)
$ pidstat -d 1 20
在这里插入图片描述

观察一会儿可以发现,的确是 app 进程在进行磁盘读,并且每秒读的数据有 32 MB,看来
就是 app 的问题。不过,app 进程到底在执行啥 I/O 操作呢?
这里,我们需要回顾一下进程用户态和内核态的区别进程想要访问磁盘,就必须使用系统调用,所以接下来,重点就是找出 app 进程的系统调用了。

跟踪进程系统调用工具-strace

**strace 正是最常用的跟踪进程系统调用的工具。**所以,我们从 pidstat 的输出中拿到进程
的 PID 号,比如 6082,然后在终端中运行 strace 命令,并用 -p 参数指定 PID 号:
在这里插入图片描述

这儿出现了一个奇怪的错误,strace 命令居然失败了,并且命令报出的错误是没有权限。
按理来说,我们所有操作都已经是以 root 用户运行了,为什么还会没有权限呢?你也可以
先想一下,碰到这种情况,你会怎么处理呢?
一般遇到这种问题时,我会先检查一下进程的状态是否正常。比如,继续在终端中运行 ps
命令,并使用 grep 找出刚才的 6082 号进程:
$ ps aux | grep 6082
系统 iowait 的问题还在继续,但是 top、pidstat 这类工具
已经不能给出更多的信息了。这时,我们就应该求助那些基于事件记录的动态追踪工具了。

基于事件记录的动态追踪工具perf

用 perf top 看看有没有新发现。再或者,可以像我一样,在终端中运行 perf
record,持续一会儿(例如 15 秒),然后按 Ctrl+C 退出,再运行 perf report 查看报
告:

$ perf record -g
$ perf report

接着,找到我们关注的 app 进程,按回车键展开调用栈,你就会得到下面这张调用关系
图:
在这里插入图片描述
这个图里的 swapper 是内核中的调度进程,你可以先忽略掉。

我们来看其他信息,你可以发现, app 的确在通过系统调用 sys_read() 读取数据。并且从
new_sync_read 和 blkdev_direct_IO 能看出,进程正在对磁盘进行直接读,也就是绕过了
系统缓存,每个读请求都会从磁盘直接读,这就可以解释我们观察到的 iowait 升高了。

看来,罪魁祸首是 app 内部进行了磁盘的直接 I/O 啊!

iowait 高排查小结

iowait 高不一定代表 I/O 有性能瓶颈。当系统中只有 I/O 类型的进程在运行时,iowait 也会很高,但实际上,磁盘的读写远
没有达到性能瓶颈的程度。
因此,碰到 iowait 升高时,需要先用 dstat、pidstat 等工具,确认是不是磁盘 I/O 的问题,然后再找是哪些进程导致了 I/O。
等待 I/O 的进程一般是不可中断状态,所以用 ps 命令找到的 D 状态(即不可中断状态)
的进程,多为可疑进程。但这个案例中,在 I/O 操作后,进程又变成了僵尸进程,所以不
能用 strace 直接分析这个进程的系统调用。
这种情况下,我们用了 perf 工具,来分析系统的 CPU 时钟事件,最终发现是直接 I/O 导
致的问题。这时,再检查源码中对应位置的问题,就很轻松了。
而僵尸进程的问题相对容易排查,使用 pstree 找出父进程后,去查看父进程的代码,检查
wait() / waitpid() 的调用,或是 SIGCHLD 信号处理函数的注册就行了。

pstree工具–查找父进程

僵尸进程是因为父进程没有回收子进程的资源而出现的,那么,要解决掉它们,就要找到它们的根儿,也就是找出父进程,然后在父进程
里解决。

父进程的找法我们前面讲过,最简单的就是运行 pstree 命令:
-a 表示输出命令行选项
p 表 PID
s 表示指定进程的父进程
$ pstree -aps 3084
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值