乐趣区

关于linux:linux性能分析篇之cpuio

1. 工具介绍

vmstat

选用 vmstat 起因:大多数的发行版根本都有此命令,然而 procinfo,pidstat,mpstat,oprofile 等命令是没有的。

[root@cubblestone ~]# vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 500488 153152 1139216 0 0 1 215 3 3 1 1 98 1 0
0 0 0 500488 153152 1139220 0 0 0 128 761 1290 0 1 99 0 0
0 0 0 500504 153152 1139220 0 0 0 0 693 1206 0 0 100 0 0
  1. procs
    r 以后可运行的过程数。也就是曾经退出了运行队列,即曾经调配了 CPU,然而并没有在期待 IO。(所以数量超过了 cpu 的个数,那么 cpu 会有瓶颈)
    b 期待 IO 实现的被阻塞的过程数。
  2. memory
    swpd 虚拟内存已应用的大小,示意以后已应用的替换页面大小。如果该值较高,示意零碎以后的物理内存不足,导致系统频繁进行页面替换。这可能会导致系统性能降落,因为磁盘操作绝对于内存访问速度较慢。
    free 未被 OS 或者程序应用的物理内存。
    buff 字段示意以后已调配给缓冲的大小(单位 KB)。较高的 buff 值通常是好的,因为它示意零碎正在无效地应用缓冲区来进步文件系统的性能。当零碎须要读取或写入文件时,能够从缓冲中获取数据,而无需间接拜访磁盘,从而放慢访问速度。
    cache 用于保留之前从硬盘读取的数据的零碎通知缓存或者内存大小(单位 KB)。如果应用程序再次须要该数据,内核能够从内存而非硬盘抓取数据,进步性能。
  3. swap
    si 每秒从磁盘读入虚拟内存的大小(单位 KB/s),如果这个值大于 0,示意物理内存不够用或者内存泄露了,要查找耗内存过程解决掉。
    so 每秒虚拟内存写入磁盘的大小(单位 KB/s),如果这个值大于 0,同上。
    注:swap 被我关掉了,所以 si 和 so 为 0。
  4. io
    bi Blocks received from a block device (blocks/s), 每秒从块设施接管到的块数,单位:块 / 秒 也就是读磁盘。
    bo Blocks sent to a block device (blocks/s), 每秒发送到块设施的块数,单位:块 / 秒 也就是写磁盘。
  5. system
    in 每秒 CPU 的中断次数,包含工夫中断
    cs 每秒上下文切换次数,例如咱们调用零碎函数,就要进行上下文切换,线程的切换,也要过程上下文切换,这个值要越小越好,太大了,要思考调低线程或者过程的数目。
  6. cpu
    us 用户 CPU 工夫。
    sy 零碎 CPU 工夫。
    id 闲暇 CPU 工夫,一般来说,id + us + sy = 100。
    wa 期待 IO CPU 工夫。

2. 做试验

2.1 起一个过程

本次试验,起一个 dd 过程,往磁盘写数据,为避免磁盘满,写个 while 循环清空磁盘。

[root@cubblestone ~]# dd if=/dev/zero of=/opt/file.txt bs=1M count=10000000000 &
[1] 23032
[root@cubblestone ~]#
[root@cubblestone ~]# while true;do sleep 1; echo "" >/opt/file.txt ;done &
[1] 22536
[root@cubblestone ~]#

2.2 继续察看 vmstat 输入后果(命令是每隔 1 秒输入一次,并且继续输入的,剖析局部内容即可)

[root@cubblestone ~]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 4  0      0 1091492  20292 675056    0    0     1   219    3    3  1  1 98  1  0
 0  1      0 1248084  20292 517664    0    0     0 154728 1444 1980  1 16 18 66  0
 1  1      0 962176  20292 803552    0    0     0 174600 2266 2548  1 18 41 41  0
 1  1      0 1274380  20292 491332    0    0     0 105992 1647 2322  0 11 18 71  0
 0  2      0 925148  20304 841484    0    0     0 199836 2035 2364  1 18 33 48  0
 0  1      0 1299008  20304 466952    0    0     0 80912 2554 7343  1 10 25 64  0
 0  2      0 893668  20304 871752    0    0     0 225740 2150 2759  2 21 31 47  0
 2  3      0 1324848  20304 439260    0    0     0 52832 2165 2765  1 13 17 70  0
 0  2      0 861524  20400 904692    0    0     0 255576 2125 3304  1 21 21 57  0
 1  0      0 1269596  20400 496764    0    0     0 23092 2235 2744  0 14 40 46  0
 1  0      0 1074792  20400 691200    0    0     0 273936 1479 1950  1 23 24 53  0
 1  1      0 983796  20404 780544    0    0    20 160248 2575 3037  3 22 42 34  0
 0  1      0 1256388  20404 507432    0    0     0 121380 2185 5755  1 11 16 72  0
 2  1      0 941968  20412 822788    0    0     0 180944 2064 2348  1 16 35 48  0
 0  1      0 1285236  20412 478680    0    0     0 97804 1873 4189  1  9 26 64  0
 0  2      0 905644  20412 858736    0    0     0 215472 1979 2225  1 18 35 46  0
 0  1      0 1309372  20412 454588    0    0     0 68196 2231 4951  1 10 31 57  0
 0  3      0 875620  20412 888492    0    0     0 239008 2422 3655  1 19 26 54  0
 0  5      0 1335960  20412 428052    0    0     0 41620 2186 2654  1  7 24 68  0
 0  2      0 848184  20516 916284    0    0     0 262316 2038 2771  3 20 14 63  0
 1  0      0 1236948  20516 527692    0    0     0 23112 2313 2608  1 11 45 44  0
 1  0      0 1146916  20516 616888    0    0     0 279528 1967 3978  1 21 15 64  0
 1  1      0 993188  20516 772152    0    0     0 157652 3020 3914  1 18 45 36  0
 0  1      0 1261300  20516 503236    0    0     0 118852 1549 2300  1 14 14 71  0

IO 和 CPU 剖析

让咱们来关注下相干字段 bi、bo、in、cs、us、sy、id、wa。

  1. 从 bi、bo 字段,咱们能够看出,由过程在疯狂向磁盘写数据,而没什么读数据的动作。疏忽第一行,写的速率在大略在 80000(块 / 秒)~ 260000(块 / 秒),我的磁盘为 /dev/vda1,所以块的大小如下

    [root@cubblestone ~]# tune2fs -l /dev/vda1 | grep "Block size"
    Block size:               4096
    [root@cubblestone ~]#
  2. 4096 字节也就是 2KB。那么也就能计算出写速率了,大略在 156(MB/s)~ 508(MB/s)。所以为什么能看出有过程在疯狂的写数据。
  3. 联合 b 字段能够看出,时不时有数个过程在期待 IO 实现。
  4. 再联合 CPU 局部,us 和 sy 都比拟小,代表用户态和内核态耗费的 CPU 不大,而 wa 的占比很高(在 30~70),代表 CPU 耗费在 IO 上的工夫很长,也能阐明有过程在疯狂 IO。(注:us+sy+id+wa+st = 100)
    然而这样并不能阐明过程就达到了瓶颈,万一人家磁盘就是好,可能反对的写速率就是很高呢,让咱们来想看下磁盘状况。

iostat

须要装置 iostat

yum install sysstat -y

命令阐明:1 秒钟输入一次后果,输入 3 次。(剖析真正的后果须要疏忽第一次的输入,命令个性,vmstat 也一样。)

[root@cubblestone yum.repos.d]# iostat -x 1 3
Linux 3.10.0-1160.71.1.el7.x86_64 (cubblestone)         06/04/2023      _x86_64_        (2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.83    0.00    0.77    0.58    0.00   97.81

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
vda               0.00     8.17    0.05    9.28     1.60   486.01   104.52     0.72   77.28   19.63   77.60   1.25   1.16
scd0              0.00     0.00    0.00    0.00     0.10     0.00   120.62     0.00    0.51    0.51    0.00   0.42   0.00

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00   18.69   37.37    0.00   43.94

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
vda               0.00     4.00    0.00  326.00     0.00 109648.00   672.69   174.38  534.91    0.00  534.91   2.58  84.20
scd0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.52    0.00    7.73   63.92    0.00   27.84

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
vda               0.00     0.00    0.00  231.00     0.00 110028.00   952.62   155.38  672.66    0.00  672.66   4.33 100.00
scd0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00

[root@cubblestone yum.repos.d]#

命令字段解释
avg-cpu 行:统计了 CPU 的均匀使用率,能够看出 iowait 达到了 30~60,跟 vmstat 的 wa 字段是一个意思。
上面才是剖析磁盘的字段。

  • rrqm/s 在提交给磁盘前,每秒被合并的读申请的数量。
  • wrqm/s 在提交给磁盘前,每秒被合并的写申请的数量。
  • r/s 每秒读取的 io 次数。
  • w/s 每秒写入的 io 次数。
  • rMB/s 示意每秒读取的数据量,单位为 MB。
  • wMB/s 示意每秒写入的数据量,单位为 MB。
  • avgrq-sz 示意均匀每个 I / O 申请的扇区数,单位为扇区。
  • avgqu-sz 示意均匀每个设施队列中的申请数量,单位为申请数量。
  • await 示意申请的均匀耗费的工夫,单位为毫秒。
  • r_await 示意读申请的均匀等待时间,单位为毫秒。
  • w_await 示意写申请的均匀等待时间,单位为毫秒。
  • svctm 示意均匀每个 I / O 申请的服务工夫,单位为毫秒。
  • %util 示意设施的利用率百分比,没有具体的单位。

想看有没瓶颈,着重关注如下几个字段
await r_await w_await svctm
await:其代表的是 IO 申请,从退出 IO 队列开始到其真正解决完数据,均匀耗费的工夫,也就是【期待 + 解决】的工夫。
r_await、w_await:跟 await 含意一样,只是从 await 中拆分进去读和写的状况。
svctm: 示意的是 IO 申请从开始解决到处理完毕耗费的均匀工夫,也就是【解决】的工夫。

以下面的命令最初一次输入的后果为例:
vda 磁盘的 await 达到了 672.66ms,而 svctm 只有 4.33ms,从他俩的差距能够看出,工夫都耗在了期待 IO 下面。

那是什么过程在产生大量的 IO 呢?

iotop

[root@cubblestone ~]# iotop -oP

由下图不言而喻:

总结

从下面的 vmstat 到上面的 iostat 咱们能够得出如下论断:

vmstat 能够看到有产生大量 IO 的过程,IO 占用 CPU 在 30%~70%,而后咱们排查是哪个磁盘在进行 IO。

iostat 能够看出是 vda 在进行大量的 IO,并且 await 曾经远远大于 svctm,所以 IO 达到了瓶颈。
而后通过 iotop 排查出是咱们的 dd 过程在疯狂写数据到 vda 磁盘。

退出移动版