非常经典的UNIX系统调优的文章
导致系统运行迟缓的原因
有许多不同的潜在的原因会导致系统运行迟缓,但通常可以将它们分为以下几个方面:
进程太多。您的系统可能仅仅只是同时运行了太多的应用程序,或者正在运行少量 CPU 密集型的操作。要么是服务器超负荷运行,要么是失控进程耗尽了系统资源。 活动内存太多。如果进程使用了大量的内存,那么系统可能会从磁盘换入大量的页面并将大量的页面换出到磁盘,这意味着您的系统花费在内存交换上的时间比真正使用内存的时间更多。 硬件故障。有时候,您会碰到导致系统运行迟缓的硬件故障。不能正常工作的网卡、硬盘或内存,都可能导致系统花费很长的时间等待信息。要对该问题进行诊断,您需要使用大量可用的工具来检查您的 Unix 系统。
选择连接方法
如果您的计算机运行得特别慢,那么第一个问题是如何连接到该计算机以便启动监视进程。运行迟缓的计算机可能无法接受 Telnet 或通过远程 Shell 协议(如 ssh)的连接。
如果您尚未登录到系统,那么可能根本无法进行访问。相反,可以考虑直接或通过独立的硬件解决方案(如网络或基于串口的控制台监视器)来使用控制台。
这种控制台更有可能允许您登录到系统,因为已经有一个登录进程(您的 Shell 将会代替它)正在运行。如果在登录到系统后,您无法通过 Shell 运行任何进程,则表示系统已经耗尽了进程空间,那么重新启动可能是使系统恢复正常的唯一办法。
要重新启动系统,请使用 init 或 telinit 来调整运行级别,运行级别 6 通常表示重新启动。使用 init/telinit 更有可能重新启动系统,因为在进行重新启动时仅涉及到了一个进程。
在系统启动并运行后,您需要使用本文中介绍的一些技巧来监视该系统的运行状态并记录其输出结果。如果再次出现系统运行迟缓的情况,您可以执行事后检查调试并分析系统运行迟缓的原因。
使用 uptime
如果您怀疑计算机运行得很慢,那么您应该运行的第一个命令是
uptime
。Uptime
报告当前时间、计算机启动和运行时间(换句话说,是从计算机启动以来的时间)以及当前的用户数。然后它会提供三幅图表,以显示最近 1 分钟、5 分钟和 15 分钟的平均负载。例如:$ uptime18:28:54 up 10 days, 8:38, 2 users, load average: 2.24, 5.34, 3.42
在这个示例中,该计算机在最近 1 分钟、5 分钟和 15 分钟内的平均负载分别超过了 2、5 和 3。
平均负载的定义比较复杂,并且受到正在执行的进程的状态影响。通常,正在运行、等待 CPU 或等待 I/O 的每个进程都会使平均负载加 1。然后对这些图表进行计算并根据时间平均。
在单 CPU 的系统中,平均负载大于 1 则表示该 CPU 难以承受您所分配的负载类型。但是因为 Unix 的多进程的本质,在您关注到该问题前,平均负载在长时间内(换句话说,对应于 15 分钟的图表)达到 2 通常是可以接受的。
在多 CPU(或多核)系统中,需要将平均负载除以 CPU 的个数。要确定计算机是否超负荷运行,请使用上述原则。
查看这些图表的另一种可选的方法是将它们看作百分比,换句话说,如果上面的图表来自于一个单 CPU 系统,那么如果该计算机的速度比目前快百分之 224,那么它就能够处理当前的负载。
在多 CPU 系统中,您应该使用 CPU 数目加 1 来确定最大负载。例如,一个 4 CPU 的系统可以承受的最大平均负载为 5。
通常在短时间内,计算机的平均负载可能比其最大平均负载高的多。例如,当构建或编译一个应用程序、或执行一项磁盘密集型任务时,平均负载可能会激增。这正是输出结果中包含 1、5 和 15 分钟平均值的原因,因为这样可以帮助消除任何瞬态负载极大值。
任何长时间的或未预料到的较高的值都可能表示存在问题,并且需要进行进一步的研究。如果这些数值较低,但系统却运行迟缓,那么可能表示存在交换空间的问题。
使用 ruptime
如果您管理着由许多系统组成的大型网络,那么有一种简单的方法来监视负载和网络中所有计算机的使用情况。ruptime 工具收集网络上所有计算机广播的数据,并将其集中到一个本地文件中,以便对所有计算机的当前状态进行检查。
例如,清单 1 显示了一个小型网络的输出结果:
清单 1. 一个小型网络的输出
$ ruptimebear up 10+09:13, 2 users, load 0.66, 0.68, 0.50ultra3up 6+01:16, 1 user, load 0.00, 0.00, 0.00atuin down 4+00:52
最后一台计算机 11 分钟内没有报告任何数据,所以将其列为停机。
要生成这些信息,需要在本地网络中的每台计算机上运行 rwhod 守护进程(有时候是 in.rwhod)。这个守护进程为本地计算机广播信息,并收集来自所有其他计算机的广播数据。
因为 rwho/ruptime 系统的工作方式的原因,所以可能存在一些性能问题,尤其是在大型的网络中,它们生成的大量的系统报告和网络流量可能是有害的。在非常繁忙的系统中,对这些数据进行广播的需求可能也就意味着永远无法报告这些信息,这些数据可能过期,或者在系统繁忙时将其报告为停机。
跟踪大型进程
如果您怀疑是一个大型的或过度繁忙的进程导致了该问题,那么您应该检查 ps 工具的输出,查找进程大小、内存百分比和 CPU 利用率。在 SVR4 系统(Solaris 和 AIX®)中,您可以使用下列命令来获得进程的列表(请参见清单 2)。
清单 2. 获得进程列表的命令
$ ps -A -o pCPU,pmem,RSS,vsz,comm%CPU %MEM RSS VSZ COMMAND0.2 0.000 fsflush0.1 0.2 1464 8288 /usr/lib/ssh/sshd0.1 0.1 1032 1320 ps0.0 1.0 9536 47608 /usr/openwin/bin/Xsun0.0 0.7 6312 10720 dtgreet0.0 0.6 6136 9352 /usr/sfw/sbin/snmpd0.0 0.4 3208 5720 /usr/lib/fm/fmd/fmd0.0 0.3 2808 8512 /usr/lib/ssh/sshd0.0 0.3 2800 8504 /usr/lib/ssh/sshd0.0 0.3 2768 8512 /usr/lib/ssh/sshd0.0 0.3 2368 4056 /usr/sbin/nscd0.0 0.2 2096 9176 /usr/dt/bin/dtlogin...
清单 3 显示了在 BSD 派生系统中的 ps 工具的输出。
清单 3. 一个 BSD 系统中获得的进程列表
$ ps -A -o pcpu,pmem,rss,vsz,command|sort -n +3%CPU %MEMRSS VSZ COMMAND 0.0 0.015227236 nfsd-server 0.0 0.015227236 nfsd-server 0.0 0.015227236 nfsd-server 0.0 0.015227236 nfsd-server 0.0 0.015227236 nfsd-server 0.0 0.015227236 nfsd-server 0.0 0.015227236 nfsd-server 0.0 0.015227236 nfsd-server 0.0 0.016427236 nfsd-master 0.0 0.022427240 /usr/sbin/update 0.0 0.3 436429196 /usr/sbin/securityd 0.0 0.2 276029288 jabberd -c /etc/jabber/jabber.xml -H/private/var/jabber/ -U jabber 0.0 0.018429300 nfsiod -n 40.0 0.2 354429712 /usr/sbin/configd 0.0 0.050030628 /usr/sbin/sshd -i 0.0 0.026030648 /usr/sbin/smbd -D 0.0 0.073630648 /usr/sbin/smbd -D 0.0 0.1 121630700 /usr/sbin/sshd -i... 0.0 0.1 218050664 imapd: narcissus.mcslp.pri [192.168.0.110]mc user.mc 0.0 0.1 218450664 imapd: sulaco.mcslp.pri [192.168.0.101]mc user.mc 0.0 0.1 220450720 imapd: narcissus.mcslp.pri [192.168.0.110]buy user.buy 0.0 0.1 226450720 imapd: sulaco.mcslp.pri [192.168.0.101] buyuser.buy 0.0 0.1 227250984 imapd: kernel.mcslp.pri [192.168.0.106] slpuser.slp 0.0 1.2 1834854368 servermgrd -x 0.0 0.2 320085920 /usr/sbin/named -f 0.0 1.1 16820 122240 /usr/libexec/mysqld --basedir=/usr--datadir=/var/mysql --user=mysql --pid-file=/var/mysq 0.0 0.5 8572 158164 /usr/libexec/slapd -d 0 -h ldap:///ldapi://%2Fvar%2Frun%2Fldapi 0.0 0.0204 289396 rpc.statd
在上面两个例子中,进程列表中显示了 CPU 和内存使用率,以便您能够清楚地了解系统中的负载情况。‘s’和‘stat’列(分别对应于 SVR4 和 BSD)显示了进程的当前状态。对于大量的运行的进程,状态‘R’表示该进程当前正在运行。
通过使用状态、CPU 和内存百分比的组合,您应该可以确定是否存在失控的 和大量消耗系统资源的进程。
使用 iostat
iostat 工具提供了关于终端、磁盘活动和 CPU 利用率的信息。您可以指定单个数值参数来设置报告的时间间隔,并指定另一个数值参数来设置报告的数量。例如,清单 4 显示了如何每 5 秒钟报告相应的统计信息。
清单 4. 每隔 5 秒报告统计信息
$ iostat 5 ttydad1 sd1 nfs1 cputin tout kps tps serv kps tps serv kps tps serv us sy wt id 07 440 39 140 030 005 18 0 77 0 39 2 000 000 000 0 0 100 0 13 4 300 000 000 0 0 100 0 13 0 000 000 000 0 0 100
对于不同的系统,缺省情况下显示的确切的信息也有所不同,清单 4 来自于一个 Solaris 系统。清单 5 中的示例来自于一个 BSD 环境。
清单 5. 一个 BSD 系统中的 iostat
disk1 disk0 cpu KB/t tps MB/s KB/t tps MB/s us sy id167.67 0 0.02 20.70 5 0.09 6 3 90 0.00 0 0.00 0.00 0 0.00 15 3 82 0.00 0 0.00 0.00 0 0.00 16 2 82 0.00 0 0.00 14.33 24 0.33 18 4 79 0.00 0 0.00 2.83 1 0.00 23 4 73
先来看看 CPU 统计信息,这些列分别显示了用户 (us)、系统 (sy) 和空闲 (id) 百分比。用户时间显示了用于该用户进程的时间。系统时间则显示了系统进程耗费的时间(在没有显示等待时间时,包括系统等待 I/O 的时间)。空闲时间显示了 CPU 处于空闲状态的时间的百分比。
磁盘的输出显示了各个物理磁盘(在合适的情况下包括 NFS 加载)的工作情况,通常以每秒处理事务数和每秒传输的 MB 或 KB 作为单位。其中的较大数值,尤其是同时具有较高的等待/系统时间,可能表示对于该系统而言,磁盘的速度太慢。您可以尝试展开您的应用程序,以便它使用不同的磁盘,这样可能可以改善它的性能。
如果该磁盘同时用作虚拟内存,那么可能是因为缺少内存和过多的交换的问题。
使用 vmstat
您可以使用 vmstat 工具来监视虚拟内存统计信息。与 iostat 一样,它接受一个数值时间间隔(请参见清单 6)。
清单 6. 使用 vmstat 监视内存统计信息
$ vmstat 5kthr memorypagedisk faults cpur b w swap free re mf pi po fr de sr dd s1 -- in sy cs us sy id0 0 0 2820888 809552 94 525 121 69 50 0 26 16 0 0 297 1342 272 9 4 870 0 0 2824752 778872 2 7 0 0 0 0 0 0 0 0 229 34 109 0 1 990 0 0 2824752 778872 0 0 0 0 0 0 0 2 0 0 233 28 116 0 0 1000 0 0 2824752 778872 0 0 0 0 0 0 0 0 0 0 228 26 110 0 0 1000 0 0 2824752 778872 0 0 0 0 0 0 0 0 0 0 229 28 111 0 0 100
vmstat 工具输出线程/进程信息、内存/交换区使用率、换进/换出页面、磁盘 I/O、页面错误和 CPU 统计信息。
CPU/线程块显示了运行队列 (r) 中的进程/线程、等待 I/O 资源的阻塞进程 (b) 和那些被交换的进程。阻塞进程列中较高的值表示磁盘的速度较慢。交换列中较高的数值表示存在许多进程使用了太多的内存,需要对它们进行换入和换出。交换是一项开销非常高的处理,并且将明显地降低系统的性能。
内存列显示了当前可用的交换区大小和空闲列表的大小(如果对 RAM 提出请求,可以被交换的页面的数目)。较低的交换值表示即将耗尽交换空间,这并不一定表示存在问题,只要您拥有足够的 RAM 来运行相应的应用程序。较低的空闲列表值可能表示使用了大量的活动 RAM,如果您向该系统中添加更多的进程,那么可能引起交换空间的使用。
页面列显示了从磁盘交换进来的和交换到磁盘的内存页面。键值列是 pi/po(换进/换出的页面),这表示了对多少页面进行了交换。较高的分页表示缺少 RAM,较高的扫描速率(sr 列)显示了潜在的内存瓶颈。
使用 top
top 工具可以提供一种有效的方法来监视活动中的系统和活动的进程、负载以及内存统计信息。有许多不同类型的 top,在缺省情况下,某些系统中安装了其中的一部分,而这些 top 是最新的开放源码版本的工具。它所提供的相关信息更像是 uptime、交换空间和 ps 工具的组合。例如,下面的输出来自于 Solaris 系统中运行的 V3.5.1 版本的 top 工具(请参见清单 7)。
清单 7. 使用 top
last pid: 9385; load averages: 7.14, 2.98, 1.2161 processes: 55 sleeping, 4 running, 1 zombIE, 1 on cpuCPU states: 0.0% idle, 93.8% user, 6.2% kernel, 0.0% iowait, 0.0% swapMemory: 1024M real, 712M free, 125M swap in use, 2705M swap free PID USERNAME LWP PRI NICE SIZE RES STATETIMECPU COMMAND 9313 root 1 220 35M 34M run 0:03 8.87% cc1 9349 root 1 220 21M 20M run 0:01 5.47% cc1 9385 root 1 390 4320K 3904K run 0:00 0.38% as 9384 root 1 290 3888K 3424K run 0:00 0.30% as 9145 root 1 590 3736K 2144K cpu 0:00 0.11% top 9180 root 1 590 1808K 1472K sleep0:00 0.10% make 486 root 1 590 46M 9536K sleep0:00 0.03% Xsun 548 root 1 590 10M 6360K sleep0:00 0.03% dtgreet 553 mc 1 490 8288K 1472K sleep0:01 0.02% sshd 9345 root 1 490 1328K 928K sleep0:00 0.01% gcc 9348 root 1 590 1328K 928K sleep0:00 0.01% gcc 9325 root 1 490 1328K 928K sleep0:00 0.01% gcc 599 mc 1 590 8288K 1488K sleep0:00 0.00% sshd 9312 root 1 590 1328K 928K sleep0:00 0.00% gcc 9 root 16 590 9464K 2016K sleep0:06 0.00%svc.configd
top 工具显示了各个进程的 CPU 使用情况,例如,在前面的示例中,可以看到正在编译大量的文件以及它们使用 CPU 的比例。
您还应该注意进程的状态:较高的运行进程的数目可能表示系统过于繁忙(将运行进程与 CPU 状态和系统的平均负载进行比较)。Top 本身可能耗费大量的 CPU,所以最好是以较大的更新时间间隔来运行它,以避免监视工作对系统性能带来损害。您可以使用
-s
或-d
命令行选项(根据您使用的平台来决定)以秒为单位来指定更新的时间间隔。使用 SAR
有些时候,您需要在系统出现问题后对其状态进行监视,但是却又无法实时监视服务器的状态,在这种情况下,您可以使用 SAR(系统活动报告程序)工具。它以指定的时间间隔将相关信息记录到一个全局文件中,然后可以在事后对该文件进行处理以显示计算机的相关信息,该工具正是以这种方式为您提供帮助。
因为记录信息的进程持续运行于后台,所以它可以用来详细地描述系统在一段时间内的性能,并且可以帮助您确定问题的原因。通常以天、月或您指定的时间间隔为单位来记录相应的信息。日志保存到 /var/log/sa/saDD 或 /usr/adm/sa/saDD,其中 DD 表示一个月中的第几天。启用 SAR 工具与具体的系统有关,并且通常您需要建立一个 cron 任务来自动地运行数据收集脚本 (sa1)。另一个脚本 sa2 可以创建每天的报告,以便您对其进行研究。例如,下面的 crontab 显示了 Solaris 系统中缺省记录的系统性能统计信息:
0 * * * 0-6 /usr/lib/sa/sa120,40 8-17 * * 1-5 /usr/lib/sa/sa15 18 * * 1-5 /usr/lib/sa/sa2 -s 8:00 -e 18:01 -i 1200 -A
在收集到了这些信息之后,可以使用
sar
命令来提取相应的数据。系统所记录下来的信息量可能非常大,并且可以从该数据中选择和提取的详细信息也非常大。然而,通过使用 SAR 的-A
命令行参数,您可以了解到数据的数量和质量,该选项报告了当前记录的所有信息。清单 8. 使用带 -A 参数的 sar 命令生成的输出
11:49:38%usr%sys%wio %idle13:20:00 1 1 0 9913:40:01 19 5 0 7614:00:00 0 0 0 10014:20:00 0 0 0 10014:40:01 0 0 0 10015:00:00 0 0 0 10015:20:00 0 0 0 100Average3 1 0 9611:49:38 device%busy avque r+w/s blks/s avwait avserv...Averagedad1 1 0.3 5 36547.3 4.5 dad1,a0 0.0 0 415.4 8.6 dad1,b0 0.0 0 0 0.013.8 dad1,c0 0.0 0 0 0.0 0.0 dad1,d1 0.2 3 14353.0 3.9 dad1,e0 0.0 0 39 117.3 5.9 dad1,h0 0.0 1 17829.0 4.6 nfs1 0 0.0 0 0 0.0 0.0 nfs2 0 0.0 0 31 0.514.5 sd1 0 0.0 0 0 0.0 3.311:49:38 runq-sz %runocc swpq-sz %swpocc13:20:00 2.0 2 0.0 013:40:01 5.3 15 0.0 014:00:00 0.0 0 0.0 014:20:00 0.0 0 0.0 014:40:01 1.5 0 0.0 015:00:00 0.0 0 0.0 015:20:00 0.0 0 0.0 0Average 5.0 2 0.0 011:49:38 bread/s lread/s %rcache bwrit/s lwrit/s %wcache pread/s pwrit/s13:20:00 0 11 97 0 1 89 0 013:40:01 0 803 100 4 381 99 0 014:00:00 0 0 100 0 0 39 0 014:20:00 0 0 100 0 0 56 0 014:40:01 0 0 100 0 0 61 0 015:00:00 0 0 100 0 0 48 0 015:20:00 0 0 100 0 0 32 0 0Average0 120 100 1 56 99 0 011:49:38 swpin/s bswin/s swpot/s bswot/s pswch/s13:20:000.00 0.00.00 0.0 30513:40:010.00 0.00.00 0.0 22314:00:000.00 0.00.00 0.0 11114:20:000.00 0.00.00 0.0 11214:40:010.00 0.00.00 0.0 11215:00:000.00 0.00.00 0.0 11415:20:000.00 0.00.00 0.0 114Average 0.00 0.00.00 0.0 15211:49:38 scall/s sread/s swrit/s fork/s exec/s rchar/s wchar/s13:20:00 526 39 260.640.59 38118 2577913:40:012288 803 3209.316.53 773352 155893414:00:00 22 2 20.010.01 342 18614:20:00 20 2 20.000.00 150 12814:40:01 20 2 20.010.00 153 12815:00:00 26 3 30.010.02 326 16715:20:00 29 3 30.020.03 641 272Average 416 125 521.461.04 118615 23279111:49:38 iget/s namei/s dirbk/s13:20:00 2 31 313:40:01 29 385 2514:00:00 0 1 014:20:00 0 0 014:40:01 0 0 015:00:00 0 1 015:20:00 0 2 0Average5 61 411:49:38 rawch/s canch/s outch/s rcvin/s xmtin/s mdmin/s13:20:00 0 0 39 0 0 013:40:01 1 0 397 0 0 014:00:00 0 0 9 0 0 014:20:00 0 0 0 0 0 014:40:01 0 0 0 0 0 015:00:00 0 0 16 0 0 015:20:00 0 0 38 0 0 0Average0 0 72 0 0 011:49:38 proc-szov inod-szov file-szov lock-sz13:20:00 53/161540 1732/696610 358/358 00/0 13:40:01 54/161540 15118/696610 358/358 00/0 14:00:00 57/161540 15120/696610 359/359 00/0 14:20:00 57/161540 15120/696610 359/359 00/0 14:40:01 57/161540 15120/696610 359/359 00/0 15:00:00 57/161540 15121/696610 359/359 00/0 15:20:00 57/161540 15127/696610 359/359 00/0 11:49:38 msg/s sema/s13:20:000.000.0013:40:010.000.0014:00:000.000.0014:20:000.000.0014:40:010.000.0015:00:000.000.0015:20:000.000.00Average 0.000.0011:49:38 atch/s pgin/s ppgin/s pflt/s vflt/s slock/s13:20:00 13.393.675.05 41.14 77.090.0013:40:01 188.449.91 25.61 373.73 1086.420.0014:00:000.300.050.060.611.590.0014:20:000.160.000.000.340.760.0014:40:010.200.000.000.481.010.0015:00:000.720.010.010.982.370.0015:20:000.890.020.021.433.470.00Average29.661.904.38 60.43 170.400.0011:49:38 pgout/s ppgout/s pgfree/s pgscan/s %ufs_ipf13:20:00 0.03 0.06 0.06 0.00 0.0013:40:01 6.4119.1813.84 0.00 0.0014:00:00 0.00 0.00 0.00 0.00 0.0014:20:00 0.00 0.00 0.00 0.00 0.0014:40:01 0.00 0.00 0.00 0.00 0.0015:00:00 0.00 0.00 0.00 0.00 0.0015:20:00 0.00 0.00 0.00 0.00 0.00Average 0.95 2.83 2.05 0.00 0.0011:49:38 freemem freeswap13:20:00 109186 573661513:40:01 95816 561482214:00:00 97408 564984914:20:00 97311 564740914:40:01 97418 565371115:00:00 97338 564898215:20:00 97333 5648993Average98516 565478411:49:38 sml_mem alloc fail lg_mem alloc fail ovsz_alloc fail13:20:00 4178176 3572465 0 38477824 32137880 014663680 013:40:01 16572672 10204085 0 99106816 80782488 015310848014:00:00 16589056 10261693 0 99106816 80797968 015343616 014:20:00 16589056 10259613 0 99106816 80736600 015343616014:40:01 16589056 10260061 0 99106816 80820088 015343616015:00:00 16589056 10267477 0 99106816 80902432 015343616015:20:00 16589056 10274757 0 99106816 80864920 015343616 0Average 14813733 9300022 0 90445528 73863192 015241801 0
在可能的情况下,对上面的输出进行了剪裁,以限制所显示的数据量(比如,并没有显示所有磁盘的统计信息)。有关 SAR 的更详细的信息,请查看参考资料部分和您的系统中的 manual 页面。
结束语
尽管在运行迟缓的 Unix 系统和您能够提取的统计信息之间可能并不存在直接的关联,但在发现系统运行迟缓的时候,第一件事就应该是收集尽可能多的信息。究竟是应该主动地(通过 ps、uptime 和其他工具)还是被动地(通过 SAR 或 top)来完成这项工作,这取决于实际情况。有了这些信息,您应该可以判断 UNIX 系统之所以运行迟缓,到底是因为负载过重(CPU 超负荷使用)、物理内存太少(大量的交换工作),还是存在失控进程(单个进程占用大量的 CPU 时间)的问题。