原文:https://netflixtechblog.com/linux-performance-analysis-in-60-000-milliseconds-accc10403c55
uptime
dmesg | tail
vmstat 1
mpstat -P ALL 1
pidstat 1
iostat -xz 1
free -m
sar -n DEV 1
sar -n TCP,ETCP 1
top
1. uptime
$ uptime
23:51:26 up 21:31, 1 user, load average: 30.02, 26.43, 19.02
这是查看负载平均值的快速方法,该平均值指示要运行的任务(进程)数。在 Linux 系统上,这些数字包括希望在 CPU 上运行的进程,以及在不间断 I/O(通常是磁盘 I/O)中被阻止的进程。这给出了资源负载(或需求)的高级概念,但如果没有其他工具,就无法正确理解。只值得快速浏览一下。
这三个数字是指数阻尼的移动和平均值,常数为 1 分钟、5 分钟和 15 分钟。这三个数字让我们了解负载如何随时间变化。例如,如果要求您检查有问题的服务器,并且 1 分钟值远低于 15 分钟值,则您可能登录太晚并错过了问题。
在上面的示例中,负载平均值显示最近增加,1 分钟值达到 30,而 15 分钟值达到 19。数字如此之大意味着很多事情:可能是 CPU 需求;VMSTAT 或 MPSTAT 将确认,这是此序列中的命令 3 和 4。
2. dmesg | tail
$ dmesg | tail
[1880957.563150] perl invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0
[...]
[1880957.563400] Out of memory: Kill process 18694 (perl) score 246 or sacrifice child
[1880957.563408] Killed process 18694 (perl) total-vm:1972392kB, anon-rss:1953348kB, file-rss:0kB
[2320864.954447] TCP: Possible SYN flooding on port 7001. Dropping request. Check SNMP counters.
这将查看最后 10 条系统消息(如果有)。查找可能导致性能问题的错误。上面的示例包括 oom-killer 和 TCP 丢弃请求。
不要错过这一步!DMESG总是值得检查的。
3.vmstat 1
$ 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
34 0 0 200889792 73708 591828 0 0 0 5 6 10 96 1 3 0 0
32 0 0 200889920 73708 591860 0 0 0 592 13284 4282 98 1 1 0 0
32 0 0 200890112 73708 591860 0 0 0 0 9501 2154 99 1 0 0 0
32 0 0 200889568 73712 591856 0 0 0 48 11900 2459 99 0 0 0 0
32 0 0 200890208 73712 591860 0 0 0 0 15898 4840 98 1 1 0 0
^C
vmstat(8) 是虚拟内存统计的缩写, 是一个常用的工具 (几十年前首次为 BSD 创建)。 它在每行上打印密钥服务器统计信息的摘要。
VMSTAT 以参数 1 运行,以打印一秒钟的摘要。输出的第一行(在此版本的 vmstat 中)有一些列显示自引导以来的平均值,而不是前一秒。现在,跳过第一行,除非您想学习并记住哪一列是哪一列。
需要检查的列:
- r:在 CPU 上运行并等待轮次的进程数。这为确定 CPU 饱和度提供了比负载平均值更好的信号,因为它不包括 I/O。解释:“r”值大于 CPU 的个数就是饱和。
- free:以 KB 为单位的可用内存。如果数字太多而无法计数,则您有足够的可用内存。“free -m” 命令(包含在命令 7 中)更好地解释了可用内存的状态。
- si, so:换入和换出。如果这些值不为零,则内存不足。
- us, sy, id, wa, st:这些是所有CPU的平均CPU时间细分。它们是用户时间、系统时间(内核)、空闲、等待 I/O 和被盗时间(由其他访客使用,或使用访客自己的独立驱动程序域使用 Xen)。
- CPU 时间细分将通过添加用户 + 系统时间来确认 CPU 是否繁忙。恒定的等待 I/O 指向磁盘瓶颈;这是 CPU 空闲的位置,因为任务在等待挂起的磁盘 I/O 时被阻止。您可以将等待 I/O 视为另一种形式的 CPU 空闲,一种提供它们空闲原因的线索。
I/O 处理需要系统时间。高系统时间平均值(超过 20%)可能会很有趣,可以进一步探索:也许内核处理 I/O 的效率低下。
在上面的示例中,CPU 时间几乎完全在用户级别,指向应用程序级别的使用情况。CPU 的平均利用率也远远超过 90%。这不一定是问题;使用“r”列检查饱和度。
4. mpstat -P ALL 1
$ mpstat -P ALL 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
07:38:49 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
07:38:50 PM all 98.47 0.00 0.75 0.00 0.00 0.00 0.00 0.00 0.00 0.78
07:38:50 PM 0 96.04 0.00 2.97 0.00 0.00 0.00 0.00 0.00 0.00 0.99
07:38:50 PM 1 97.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 2.00
07:38:50 PM 2 98.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00
07:38:50 PM 3 96.97 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.03
[...]
此命令打印每个 CPU 的 CPU 时间细分,可用于检查不平衡。单个热 CPU 可能是单线程应用程序的证据。
5. pidstat 1
$ pidstat 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
07:41:02 PM UID PID %usr %system %guest %CPU CPU Command
07:41:03 PM 0 9 0.00 0.94 0.00 0.94 1 rcuos/0
07:41:03 PM 0 4214 5.66 5.66 0.00 11.32 15 mesos-slave
07:41:03 PM 0 4354 0.94 0.94 0.00 1.89 8 java
07:41:03 PM 0 6521 1596.23 1.89 0.00 1598.11 27 java
07:41:03 PM 0 6564 1571.70 7.55 0.00 1579.25 28 java
07:41:03 PM 60004 60154 0.94 4.72 0.00 5.66 9 pidstat
07:41:03 PM UID PID %usr %system %guest %CPU CPU Command
07:41:04 PM 0 4214 6.00 2.00 0.00 8.00 15 mesos-slave
07:41:04 PM 0 6521 1590.00 1.00 0.00 1591.00 27 java
07:41:04 PM 0 6564 1573.00 10.00 0.00 1583.00 28 java
07:41:04 PM 108 6718 1.00 0.00 0.00 1.00 0 snmp-pass
07:41:04 PM 60004 60154 1.00 4.00 0.00 5.00 9 pidstat
^C
Pidstat有点像top的每个进程摘要,但打印的是滚动摘要而不是清除屏幕。这对于观察一段时间内的模式以及将您看到的内容(复制粘贴)记录到调查记录中非常有用。
上面的示例将两个 Java 进程标识为负责消耗 CPU。%CPU 列是所有 CPU 的总数;1591% 表明 Java 进程消耗了近 16 个 CPU。
6. iostat -xz 1
$ iostat -xz 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
73.96 0.00 3.73 0.03 0.06 22.21
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
xvda 0.00 0.23 0.21 0.18 4.52 2.08 34.37 0.00 9.98 13.80 5.42 2.44 0.09
xvdb 0.01 0.00 1.02 8.94 127.97 598.53 145.79 0.00 0.43 1.78 0.28 0.25 0.25
xvdc 0.01 0.00 1.02 8.86 127.79 595.94 146.50 0.00 0.45 1.82 0.30 0.27 0.26
dm-0 0.00 0.00 0.69 2.32 10.47 31.69 28.01 0.01 3.23 0.71 3.98 0.13 0.04
dm-1 0.00 0.00 0.00 0.94 0.01 3.78 8.00 0.33 345.84 0.04 346.81 0.01 0.00
dm-2 0.00 0.00 0.09 0.07 1.35 0.36 22.50 0.00 2.55 0.23 5.62 1.78 0.03
[...]
^C
这是了解块设备(磁盘)的绝佳工具,包括应用的工作负载和由此产生的性能。查找:
- r/s、w/s、rkB/s、wkB/s:这些是每秒向设备交付的读取、写入、读取 KB 和写入 KB。使用它们进行工作负载表征。性能问题可能只是由于施加了过多的负载。
- await:I/O 的平均时间(以毫秒为单位)。这是应用程序遭受的时间,因为它包括排队时间和正在处理的时间。平均时间大于预期可能表示设备饱和或设备问题。
- avgqu-sz:向设备发出的平均请求数。大于 1 的值可能是饱和的证据(尽管设备通常可以并行处理请求,尤其是面向多个后端磁盘的虚拟设备。
- %util::设备利用率。这实际上是一个繁忙的百分比,显示设备每秒工作的时间。大于 60% 的值通常会导致性能不佳(应在 await 中看到),尽管这取决于设备。接近 100% 的值通常表示饱和度。
如果存储设备是面向许多后端磁盘的逻辑磁盘设备,则 100% 利用率可能仅意味着某些 I/O 正在 100% 的时间内进行处理,但是,后端磁盘可能远未饱和,并且可能能够处理更多的工作。
请记住,性能不佳的磁盘 I/O 不一定是应用程序问题。许多技术通常用于异步执行 I/O,以便应用程序不会直接阻塞和遭受延迟(例如,预读读取和写入缓冲)。
7. free -m
$ free -m
total used free shared buffers cached
Mem: 245998 24545 221453 83 59 541
-/+ buffers/cache: 23944 222053
Swap: 0 0 0
右两列显示:
buffers:用于缓冲区缓存,用于块设备 I/O。
cached:用于文件系统使用的页面缓存。
我们只想检查它们的大小是否接近于零,这可能会导致更高的磁盘 I/O(使用 iostat 确认)和更差的性能。上面的示例看起来不错,每个都包含许多 MB。
“-/+ buffers/cache”为已用内存和可用内存提供了较少混淆的值。Linux 使用可用内存作为缓存,但如果应用程序需要,可以快速回收它。因此,在某种程度上,缓存的内存应该包含在可用内存列中,这一行就是这样做的。甚至还有一个网站,linuxatemyram,关于这种混乱。
如果在 Linux 上使用 ZFS,就像我们对某些服务所做的那样,可能会感到困惑,因为 ZFS 有自己的文件系统缓存,而空闲的 -m 列没有正确反映。看起来系统的可用内存不足,而实际上该内存可以根据需要从 ZFS 缓存中使用。
8. sar -n DEV 1
$ sar -n DEV 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
12:16:48 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
12:16:49 AM eth0 18763.00 5032.00 20686.42 478.30 0.00 0.00 0.00 0.00
12:16:49 AM lo 14.00 14.00 1.36 1.36 0.00 0.00 0.00 0.00
12:16:49 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:16:49 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
12:16:50 AM eth0 19763.00 5101.00 21999.10 482.56 0.00 0.00 0.00 0.00
12:16:50 AM lo 20.00 20.00 3.25 3.25 0.00 0.00 0.00 0.00
12:16:50 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
^C
使用此工具检查网络接口吞吐量:rxkB/s 和 txkB/s,作为工作负载的度量,还可以检查是否已达到任何限制。在上面的例子中,eth0 接收达到 22 MB/s,即 176 Mbits/秒(远低于 1 Gbit/秒的限制)
9. sar -n TCP,ETCP 1
$ sar -n TCP,ETCP 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
12:17:19 AM active/s passive/s iseg/s oseg/s
12:17:20 AM 1.00 0.00 10233.00 18846.00
12:17:19 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
12:17:20 AM 0.00 0.00 0.00 0.00 0.00
12:17:20 AM active/s passive/s iseg/s oseg/s
12:17:21 AM 1.00 0.00 8359.00 6039.00
12:17:20 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
12:17:21 AM 0.00 0.00 0.00 0.00 0.00
^C
这是一些关键 TCP 指标的汇总视图。其中包括:
- active/s:每秒本地启动的TCP连接数(例如,通过connect())。
- passive/s:每秒远程启动的TCP连接数(例如,通过accept())。
- retrans/s:每秒 TCP 重新传输的次数。
主动和被动计数通常可用于粗略衡量服务器负载:新接受的连接数(被动)和下游连接数(主动)。将主动视为出站,将被动视为入站可能会有所帮助,但这并不完全正确(例如,考虑本地主机到本地主机的连接)。
重新传输是网络或服务器问题的征兆;它可能是一个不可靠的网络(例如,公共互联网),或者可能是由于服务器过载并丢弃数据包。上面的示例仅显示每秒新建一个 TCP 连接。
10. top
$ top
top - 00:15:40 up 21:56, 1 user, load average: 31.09, 29.87, 29.92
Tasks: 871 total, 1 running, 868 sleeping, 0 stopped, 2 zombie
%Cpu(s): 96.8 us, 0.4 sy, 0.0 ni, 2.7 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 25190241+total, 24921688 used, 22698073+free, 60448 buffers
KiB Swap: 0 total, 0 used, 0 free. 554208 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20248 root 20 0 0.227t 0.012t 18748 S 3090 5.2 29812:58 java
4213 root 20 0 2722544 64640 44232 S 23.5 0.0 233:35.37 mesos-slave
66128 titancl+ 20 0 24344 2332 1172 R 1.0 0.0 0:00.07 top
5235 root 20 0 38.227g 547004 49996 S 0.7 0.2 2:02.74 java
4299 root 20 0 20.015g 2.682g 16836 S 0.3 1.1 33:14.42 java
1 root 20 0 33620 2920 1496 S 0.0 0.0 0:03.82 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.02 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:05.35 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
6 root 20 0 0 0 0 S 0.0 0.0 0:06.94 kworker/u256:0
8 root 20 0 0 0 0 S 0.0 0.0 2:38.05 rcu_sched
top 命令包含我们之前检查的许多指标。运行它以查看是否有任何内容看起来与早期的命令大不相同,这将表明负载是可变的,这可能很方便。
缺点是随着时间的推移,很难看到模式,这在提供滚动输出的 vmstat 和 pidstat 等工具中可能更清晰。如果您没有足够快地暂停输出(按 Ctrl-S 暂停,按 Ctrl-Q 继续),并且屏幕清除,则间歇性问题的证据也可能丢失。