Load Average
本文总结了一些常见的 Linux 系统监控指标,和它们的计算方式,作为备忘笔记。
CPU 使用率
CPU 使用率衡量的是程序运行占用的 CPU 百分比。Linux 的 CPU 使用率信息可以通过/proc/stat 文件计算得到。/proc/stat包含了所有 CPU 活动的信息,该文件中的所有值都是从系统启动开始累计的,单位为 jiffies。如下图所示,cpu 一行指的是总的 CPU 信息,cpu0、cpu1、cpu2、cpu3 几行指的是 CPU 各个核的 CPU 信息。从这里也可以看出这台服务器共有 4 个核。每列从左到右的意思为
- **user:**从系统启动开始累计到当前时刻,用户态的 CPU 时间 ,不包含 nice 值为负进程所占用的时间
- **nice:**从系统启动开始累计到当前时刻,nice 值为负的进程所占用的 CPU 时间
- **system:**从系统启动开始累计到当前时刻,内核态时间
- **idle:**从系统启动开始累计到当前时刻,除硬盘 IO 等待时间以外其它等待时间
- **iowait:**从系统启动开始累计到当前时刻,硬盘 IO 等待时间
- **irq:**从系统启动开始累计到当前时刻,硬中断时间
- **softirq:**从系统启动开始累计到当前时刻,软中断时间
- **steal:**在虚拟环境下 CPU 花在处理其他操作系统的时间,Linux 2.6.11 开始才开始支持。
- **guest:**在 Linux 内核控制下 CPU 为 guest 操作系统运行虚拟 CPU 的时间,Linux 2.6.24 开始才开始支持。
- guest_nice: 在 Linux 内核控制下 CPU 为 guest 操作系统在虚拟 CPU 中运行 nice 进程的时间,Linux 2.6.33 开始才开始支持。
|
|
根据这些信息,就可以计算出 CPU 使用率。网管 Agent 的 CPU 使用率采集算法如下(以 CPU0 为例):
- cat /proc/stat | grep ‘cpu0’得到 cpu0 的信息
- cpu_total1=user+nice+system+idle+iowait+irq+softirq
- cpu_used1=user+nice+system+irq+softirq
- sleep 15 秒
- 再次 cat /proc/stat | grep ‘cpu0’得到 cpu 的信息
- cpu_total2=user+nice+system+idle+iowait+irq+softirq
- cpu_used2=user+nice+system+irq+softirq
- 得到 cpu0 在 15 秒内的平均使用率:(cpu_used2 - cpu_used1) / (cpu_total2 - cpu_total1) * 100%
每分钟会采集 4 次 15 秒内的 CPU 平均使用率。为了避免漏采集 CPU 峰值,可以取这一分钟内四次采集的最大值上报。
CPU 负载
系统负载指的是计算机系统执行计算工作的表现,CPU 负载指的是在一段时间内计算机的系统负载,一般用 1 分钟内、5 分钟内、15 分钟内这三个数字衡量。通过 uptime命令可以显示 CPU 负载。
|
|
- 对于单核单 CPU,CPU 负载为 0 表示 CPU 完全空闲,CPU 负载为 1.00 表示 CPU 恰好发挥其最大能力,CPU 负载大于 1 表示系统过载,有进程正在等待调度
- 对于多核或者多 CPU 系统,CPU 负载为每个核的 CPU 负载总和
关于 CPU 负载的计算机制,可以参考我的另一篇博客。
内存
free命令通过读取 /proc/meminfo,可以显示系统中的使用的和空闲的物理内存、Swap 内存,同时也可以显示内核使用的 buffer 和 cache,如下图所示。
|
|
其中各个字段意义为:
- total:所有可以使用的内存(包括/proc/meminfo 中的 MemTotal 和 SwapTotal)
- used:使用的内存,通过
total - free - buffers - cache计算得到 - free:没有使用的内存(包括/proc/meminfo 中的 MemFree 和 SwapFree)
- shared:主要是指 tmpfs 使用的内存,现在已经废弃不用,总是为 0
- buffers:被内核 Buffers 使用的内存
- cache:被内核的 Page Cache 和 Slab 使用的内存
- buff/cache:buffers 和 cache 的总和
- available:对于开启一个新的应用还能使用多少内存的估计,不同于 cache 和 free 内存外,还考虑了 page cache 和可再回收的 slab 内存
磁盘 IO
可以通过 iostat命令来监测磁盘的 IO 活动,它通过读取 /proc/diskstats文件来获取相关信息。
|
|
hda 后的各个参数含义如下:
Field 1 -- # of reads completed
Field 2 -- # of reads merged, field 6 -- # of writes merged
为了提高IO的效率,两个相邻的读写操作会被合并,所以两个4K的读操作在提交给磁盘之前会被合并为一个8K的读操作,杜宇磁盘来说只会视作只有一个读操作。
Field 3 -- # of sectors read
Field 4 -- # of milliseconds spent reading
Field 5 -- # of writes completed
Field 6 -- # of writes merged
Field 7 -- # of sectors written
Field 8 -- # of milliseconds spent writing
Field 9 -- # of I/Os currently in progress
Field 10 -- # of milliseconds spent doing I/Os
Field 12 -- # of discards completed
Field 13 -- # of discards merged
Field 14 -- # of sectors discarded
Field 15 -- # of milliseconds spent discarding
跟记录 CPU 信息的/proc/stat 文件一样,/proc/diskstats 中每个字段的数值也是从系统启动后一直累加的。通过这些参数,可以计算出通过 iostat命令算出的参数,具体可以参考iostat 。我们用 delta 来表示在时间 t 内某个字段的增量。例如定义 delta(reads merged)为当前 reads merged 的值减去 t 秒前 reads merged 的值。
- rrqm/s:delta(reads merged) / t (得到时间 t 内平均每秒 reads merged 的值)
- wrqm/s:delta(writes merged) / t
- r/s:delta(reads completed) / t
- w/s:delta(writes completed) / t
- rsec/s:delta(sectors read) / t
- wsec/s:delta(sectors written) / t
- rkB/s:delta(sectors read) / t / 2 (因为 1 扇区为 512 字节,所以 rkB/s 为 rsec/s 的一半)
- wkB/s:delta(sectors written) / t / 2
- avgrq-sz:(delta(sectors read) + delta(sectors written)) / (delta(reads completed) + delta(writes completed))
- avgqu-sz:**delta(*weighted time spent doing I/Os*) / t / 1000 (单位为毫秒,所以除以 1000)
- await:(delta(time spent reading) + delta(time spent writing)) / (delta(reads completed) + delta(writes completed))
- **svctm:**delta(time spent doing I/Os)/ (delta(reads completed) + delta(writes completed))**
- **%util:**delta(time spent doing I/Os) / t / 1000 * 100%
所有磁盘汇总采集项:
| 采集项 | 采集项说明 | 是否乘以 100 以保留精度 |
|---|---|---|
| avgqu_sz_max | 所有磁盘 avgqu_sz 最大值 | 是 |
| svctm_time_max | 所有磁盘 svctm 最大值 | 是 |
| await_time_max | 所有磁盘 await 最大值 | 是 |
| util_max | 所有磁盘%util 最大值 | 否 |
| disk_total_read | 所有磁盘的 r/s 总和 | 是 |
| disk_total_write | 所有磁盘的 w/s 总和 | 是 |
| 磁盘 IO disk_block_in | 所有磁盘的 rkB/s 总和。bi 即 block in,表示从块设备(如磁盘)读取的块数。Linux 块设备的块大小都为 1024 字节,所以 disk_bi 等于 rkB/s。 | 否 |
| 磁盘 IO disk_block_out | 所有磁盘的 rkB/s 总和 bo 即 block out,表示发给块设备的块数,即写磁盘。Linux 块设备的块大小都为 1024 字节,所以 disk_bi 等于 wkB/s。 | 否 |
单个磁盘采集项:
对于安装了 1 个以上的磁盘的服务器,可以采集单个磁盘的 IO 数据。最多支持 24 个盘。
| 采集项 | 采集项说明 | 是否乘以 100 以保留精度 |
|---|---|---|
| disk_n_util(n 为 0-23) | 第 n 个磁盘的%util 值 | 否 |
| disk_n_await | 第 n 个磁盘的 await 值 | 是 |
| disk_n_read | 第 n 个磁盘的 r/s 值 | 是 |
| disk_n_write | 第 n 个磁盘的 w/s 值 | 是 |
| disk_n_block_in | 第 n 个磁盘的 rkB/s 值 | 否 |
| disk_n_block_out | 第 n 个磁盘的 wkB/s 值 | 否 |
网络 IO
流量包量
通过 /proc/net/dev文件,可以计算出服务器的流量及包量。
|
|
与记录 CPU 信息的 /proc/stat文件类似,/proc/net/dev中的数值,也是从系统启动后一直累加的。
计算网卡流量方法如下:
- 读取/proc/net/dev 文件,获取 eth0 的 Receive bytes、Receive packets、Transmit bytes、Transmit packets,分别记为 receive_bytes0、receive_packets0、transmit_bytes0、transmit_packets0
- sleep 60 秒
- 再次读取/proc/net/dev 文件,获取 eth0 的 Receive bytes、Receive packets、Transmit bytes、Transmit packets,分别记为 receive_bytes1、receive_packets1、transmit_bytes1、transmit_packets1
- 根据 60 秒前后的/proc/net/dev 文件,便可计算出下面的指标:
- 60 秒内平均每秒入流量:(receive_bytes1 - receive_bytes0) * 8 / 60 / 1000 (kbps)(乘以 8 是为了把 bytes 转成 bit,除以 1000 是为了把单位转成 k,除以 60 则是取 60 秒内的平均值)
- 60 秒内平均每秒出流量:(transmit_bytes1 - transmit_bytes0) * 8 / 60 / 1000 (kbps)
- 60 秒内平均每秒入包数:(receive_packets1 - receive_packets0) / 60 (个)
- 60 秒内平均每秒出包数:(transmit_packets1 - transmit_packets0) / 60 (个)
TCP 连接数
/proc/net/snmp记录了一些 TCP 信息,其中比较有用的是 CurrEstab字段,即当前已建立的 TCP 连接数。
|
|
UDP 接收和发送数据报
/proc/net/snmp还记录了一些 UDP 信息,其中比较有用的是 InDatagrams及 OutDatagrams字段。
UDP 接收和发送数据报计算方法与 /proc/net/dev类似,步骤如下:
- 读取/proc/net/snmp 得到 InDatagrams 及 OutDatagrams,分别记为 in_data0 和 out_data0
- Sleep 240 秒
- 再次读取/proc/net/snmp 得到 InDatagrams 及 OutDatagrams,分别记为 in_data1 和 out_data1
- 根据 240 秒前后的/proc/net/snmp 文件,便可计算下面两个指标:
- 240 秒内平均每秒 UDP 入数据报:(in_data1 - in_data0) / 240
- 240 秒内平均每秒 UDP 出数据报:(out_data1 - out_data0) / 240
- UDP 数据每 240 上报一次。
参考资料
-
No backlinks found.