Linux性能调优

当遇到 I/O 性能问题时,可以使用 iostat、iotop、 blktrace 等工具分析磁盘 I/O 的瓶颈。

查看/proc/<pid>/下的的meminfo、status等文件可以具体才看到虚拟内存和实际物理内存 的使用情况。

查看cpu个数:grep 'model name' /proc/cpuinfo | wc -l

使用 uptime 命令查看三个不同时间间隔的平均值,如果 1 分钟、5 分钟、15 分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳。

案例

基于 Ubuntu 18.04,预先安装 stress 和 sysstat 包
apt install stress sysstat
sudo apt install stress

场景一:CPU 密集型进程

运行 stress 命令,模拟一个 CPU 使用率 100% 的场景:
在一个终端执行:stress --cpu 1 --timeout 600
在另一个终端执行:watch -d uptime
在第三个终端运行 mpstat 查看 CPU 使用率的变化情况:

# -P ALL 表示监控所有 CPU,后面数字 5 表示间隔 5 秒后输出一组数据
root@davinci-mini:/home/HwHiAiUser# mpstat -P ALL 5
Linux 4.19.90+ (davinci-mini)   12/23/21        _aarch64_       (8 CPU)

18:28:02     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
18:28:07     all   13.48    0.00    3.14    0.05    0.00    0.05    0.00    0.00    0.00   83.27
18:28:07       0   19.18    0.00    2.45    0.00    0.00    0.20    0.00    0.00    0.00   78.16
18:28:07       1   18.53    0.00    3.67    0.00    0.00    0.00    0.00    0.00    0.00   77.80
18:28:07       2   20.69    0.00    5.07    0.00    0.00    0.00    0.00    0.00    0.00   74.24
18:28:07       3   19.31    0.00    4.88    0.00    0.00    0.00    0.00    0.00    0.00   75.81
18:28:07       4   15.31    0.00    4.29    0.00    0.00    0.20    0.00    0.00    0.00   80.20
18:28:07       5   15.27    0.00    4.68    0.41    0.00    0.20    0.00    0.00    0.00   79.43
18:28:07       6    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
18:28:07       7    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00

查看哪个进程导致了 CPU 使用率高,可以使用 pidstat 来查询:

# 间隔 5 秒后输出一组数据
root@davinci-mini:/home/HwHiAiUser# pidstat -u 5 1
Linux 4.19.90+ (davinci-mini)   12/23/21        _aarch64_       (8 CPU)

18:30:20      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
18:30:25        0        10    0.00    0.20    0.00    0.00    0.20     3  rcu_sched
18:30:25        0      1007    0.20    0.00    0.00    0.00    0.20     0  systemd-journal
18:30:25      100      1370    0.00    0.20    0.00    0.00    0.20     0  systemd-network
18:30:25        0      1883    0.00    0.20    0.00    0.00    0.20     2  drvlog_work_0
18:30:25     1000      2207    0.00    0.20    0.00    0.00    0.20     0  dmp_daemon
18:30:25        0      2352    2.59    1.59    0.00    0.00    4.18     5  analyzer
18:30:25        0      2406    0.20    0.00    0.00    0.00    0.20     3  alertmanager
18:30:25        0      2709    0.00    0.20    0.00    0.00    0.20     5  npu-smi
18:30:25        0      8552    0.20    0.40    0.00    0.00    0.60     1  pidstat
18:30:25        0     10352    0.00    0.20    0.00    0.00    0.20     5  kworker/5:1H-kblockd
18:30:25        0     12070    8.37    0.80    0.00    0.00    9.16     2  java
18:30:25        0     14614    0.20    1.20    0.00    0.00    1.39     4  stream
18:30:25        0     24877    0.00    0.20    0.00    0.00    0.20     0  kworker/0:2-events
18:30:25        0     25422   93.43   20.32    0.00    0.00  100.00     3  vmr-lite

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

运行 stress 命令,但这次模拟 I/O 压力,即不停地执行 sync:
在一个终端执行:stress -i 1 --timeout 600
在第二个终端运行 uptime 查看平均负载的变化情况:watch -d uptime
第三个终端运行 mpstat 查看 CPU 使用率的变化情况:

# 显示所有 CPU 的指标,并在间隔 5 秒输出一组数据
mpstat -P ALL 5 1

可以看到iowait导致平均负载升高

哪个进程,导致 iowait 这么高呢?我们还是用 pidstat 来查询:

 # 间隔 5 秒后输出一组数据,-u 表示 CPU 指标
pidstat -u 5 1

可以发现,是 stress 进程导致的。

场景三:大量进程的场景

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

由于系统只有 2 个 CPU,明显比 8 个进程要少得多,因而,系统的 CPU 处于严重过载状态, 平均负载高达 7.97:

uptime
..., load average: 7.97, 5.93, 3.02

接着再运行 pidstat 来看一下进程的情况:

 # 间隔 5 秒后输出一组数据,-u 表示 CPU 指标
pidstat -u 5 1

8 个进程在争抢 2 个 CPU,每个进程等待 CPU 的时间(也就是代码块中的 %wait 列)高达 75%。这些超出 CPU 计算能力的进程,最终导致 CPU 过载。

小结

平均负载高有可能是 CPU 密集型进程导致的;
平均负载高并不一定代表 CPU 使用率高,还有可能是 I/O 更繁忙了;
当发现负载高的时候,你可以使用 mpstat、pidstat 等工具,辅助分析负载的来源。

上下文切换导致负载高

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

HwHiAiUser@davinci-mini:~$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 2297856 1048880 1900820    0    0     1    18    2    0 19  4 77  0  0
 3  0      0 2344436 1048880 1900856    0    0     0    85 25325 50968 22  5 74  0  0
 6  0      0 2424336 1048888 1900860    0    0     0   160 25343 49313 15  4 81  0  0
 2  0      0 2433636 1048888 1900868    0    0     0   100 24543 48054 23  4 72  0  0
 3  0      0 2437372 1048888 1900880    0    0     0    95 23893 48505 21  4 75  0  0

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

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

HwHiAiUser@davinci-mini:~$ pidstat -w 5
Linux 4.19.90+ (davinci-mini)   12/23/21        _aarch64_       (8 CPU)

18:57:58      UID       PID   cswch/s nvcswch/s  Command
18:58:03        0         1      0.20      0.00  systemd
18:58:03        0         9     10.76      0.80  ksoftirqd/0
18:58:03        0        10    113.55      0.00  rcu_sched
18:58:03        0        12      0.40      0.00  migration/0
18:58:03        0        15      0.40      0.00  migration/1
18:58:03        0        16      0.40      0.00  ksoftirqd/1

这个结果中有两列内容是我们的重点关注对象。
一个是 cswch ,表示每秒自愿上下文切换 (voluntary context switches)的次数。
另一个则是 nvcswch ,表示每秒非自愿上下文切换 (non voluntary context switches)的次数。

案例

使用 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%,说明 CPU 主要是被内核占用了。
in 列:中断次数也上升到了 1 万左右,说明中断处理也是个潜在的问题。

综合这几个指标,我们可以知道,系统的就绪队列过长,也就是正在运行和等待 CPU 的进程数过多,导致了大量的上下文切换,而上下文切换又导致了系统 CPU 的占用率升高。

那么到底是什么进程导致了这些问题呢?
在第三个终端再用 pidstat 来看一下, CPU 和进程上下文切换的情况:

# -w 参数表示输出进程切换指标,而 -u 参数则表示输出 CPU 使用指标
# -wt 参数表示输出线程的上下文切换指标
HwHiAiUser@davinci-mini:~$ pidstat -w -u 1
Linux 4.19.90+ (davinci-mini)   12/23/21        _aarch64_       (8 CPU)

19:05:01      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
19:05:02        0        10    0.00    0.98    0.00    0.00    0.98     1  rcu_sched
19:05:02        0      1483    0.98    0.00    0.00    0.00    0.98     3  prometheus
19:05:02        0      1904    5.88    0.00    0.00    0.00    5.88     1  java
19:05:02        0      2452    1.96    2.94    0.00    0.00    4.90     1  stream
19:05:02        0     21148   82.35   22.55    0.00    0.00  100.00     5  vmr-lite
19:05:02        0     22155   99.02   11.76    0.00    0.00  100.00     1  analyzer
19:05:02     1000     23640    0.98    0.98    0.00    0.00    1.96     3  pidstat

中断

从 /proc/interrupts 这个只读文件中读取。/proc 实际上是 Linux 的一个虚拟文 件系统,用于内核空间与用户空间之间的通信。/proc/interrupts 就是这种通信机制的一部分, 提供了一个只读的中断使用情况。

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

小结:

首先通过uptime查看系统负载,然后使用mpstat结合pidstat来初步判断到底 是cpu计算量大还是进程争抢过大或者是io过多,接着使用vmstat分析切换次数,以及切换 类型,来进一步判断到底是io过多导致问题还是进程争抢激烈导致问题。

# 并发 10 个请求测试 Nginx 性能,总共测试 100 个请求
$ ab -c 10 -n 100 http://192.168.0.10:10000/
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容