如果你的Linux服務(wù)器突然負(fù)載暴增碟绑,告警短信快發(fā)爆你的手機(jī),如何在最短時(shí)間內(nèi)找出Linux性能問題所在?Netflix性能工程團(tuán)隊(duì)的Brendan Gregg寫下了這篇博文,來看他們是怎樣通過十條命令在一分鐘內(nèi)對(duì)機(jī)器性能問題進(jìn)行診斷古戴。
概述
通過執(zhí)行以下命令劲赠,可以在1分鐘內(nèi)對(duì)系統(tǒng)資源使用情況有個(gè)大致的了解。
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
其中一些命令需要安裝sysstat包峡竣,有一些由procps包提供靠抑。這些命令的輸出,有助于快速定位性能瓶頸适掰,檢查出所有資源(CPU颂碧、內(nèi)存、磁盤IO等)的利用率(utilization)类浪、飽和度(saturation)和錯(cuò)誤(error)度量载城,也就是所謂的USE方法。
下面我們來逐一介紹下這些命令费就,有關(guān)這些命令更多的參數(shù)和說明诉瓦,請參照命令的手冊。
- uptime
$ uptime 23:51:26 up 21:31, 1 user, load average: 30.02, 26.43, 19.02
這個(gè)命令可以快速查看機(jī)器的負(fù)載情況力细。在Linux系統(tǒng)中垦搬,這些數(shù)據(jù)表示等待CPU資源的進(jìn)程和阻塞在不可中斷IO進(jìn)程(進(jìn)程狀態(tài)為D)的數(shù)量。這些數(shù)據(jù)可以讓我們對(duì)系統(tǒng)資源使用有一個(gè)宏觀的了解艳汽。
命令的輸出分別表示1分鐘猴贰、5分鐘、15分鐘的平均負(fù)載情況河狐。通過這三個(gè)數(shù)據(jù)米绕,可以了解服務(wù)器負(fù)載是在趨于緊張還是區(qū)域緩解。如果1分鐘平均負(fù)載很高馋艺,而15分鐘平均負(fù)載很低栅干,說明服務(wù)器正在命令高負(fù)載情況,需要進(jìn)一步排查CPU資源都消耗在了哪里捐祠。反之碱鳞,如果15分鐘平均負(fù)載很高,1分鐘平均負(fù)載較低踱蛀,則有可能是CPU資源緊張時(shí)刻已經(jīng)過去窿给。
上面例子中的輸出贵白,可以看見最近1分鐘的平均負(fù)載非常高,且遠(yuǎn)高于最近15分鐘負(fù)載崩泡,因此我們需要繼續(xù)排查當(dāng)前系統(tǒng)中有什么進(jìn)程消耗了大量的資源禁荒。可以通過下文將會(huì)介紹的vmstat角撞、mpstat等命令進(jìn)一步排查呛伴。
- 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.
該命令會(huì)輸出系統(tǒng)日志的最后10行。示例中的輸出谒所,可以看見一次內(nèi)核的oom kill和一次TCP丟包热康。這些日志可以幫助排查性能問題。千萬不要忘了這一步劣领。
- 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) 命令褐隆,每行會(huì)輸出一些系統(tǒng)核心指標(biāo),這些指標(biāo)可以讓我們更詳細(xì)的了解系統(tǒng)狀態(tài)剖踊。后面跟的參數(shù)1庶弃,表示每秒輸出一次統(tǒng)計(jì)信息,表頭提示了每一列的含義德澈,這幾介紹一些和性能調(diào)優(yōu)相關(guān)的列:
r:等待在CPU資源的進(jìn)程數(shù)歇攻。這個(gè)數(shù)據(jù)比平均負(fù)載更加能夠體現(xiàn)CPU負(fù)載情況,數(shù)據(jù)中不包含等待IO的進(jìn)程梆造。如果這個(gè)數(shù)值大于機(jī)器CPU核數(shù)缴守,那么機(jī)器的CPU資源已經(jīng)飽和。
free:系統(tǒng)可用內(nèi)存數(shù)(以千字節(jié)為單位)镇辉,如果剩余內(nèi)存不足屡穗,也會(huì)導(dǎo)致系統(tǒng)性能問題。下文介紹到的free命令忽肛,可以更詳細(xì)的了解系統(tǒng)內(nèi)存的使用情況村砂。
si, so:交換區(qū)寫入和讀取的數(shù)量。如果這個(gè)數(shù)據(jù)不為0屹逛,說明系統(tǒng)已經(jīng)在使用交換區(qū)(swap)础废,機(jī)器物理內(nèi)存已經(jīng)不足。
us, sy, id, wa, st:這些都代表了CPU時(shí)間的消耗罕模,它們分別表示用戶時(shí)間(user)评腺、系統(tǒng)(內(nèi)核)時(shí)間(sys)、空閑時(shí)間(idle)淑掌、IO等待時(shí)間(wait)和被偷走的時(shí)間(stolen蒿讥,一般被其他虛擬機(jī)消耗)。上述這些CPU時(shí)間,可以讓我們很快了解CPU是否出于繁忙狀態(tài)芋绸。一般情況下媒殉,如果用戶時(shí)間和系統(tǒng)時(shí)間相加非常大,CPU出于忙于執(zhí)行指令侥钳。如果IO等待時(shí)間很長,那么系統(tǒng)的瓶頸可能在磁盤IO柄错。
示例命令的輸出可以看見舷夺,大量CPU時(shí)間消耗在用戶態(tài),也就是用戶應(yīng)用程序消耗了CPU時(shí)間售貌。這不一定是性能問題给猾,需要結(jié)合r隊(duì)列,一起分析颂跨。
- 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
[...]
該命令可以顯示每個(gè)CPU的占用情況敢伸,如果有一個(gè)CPU占用率特別高,那么有可能是一個(gè)單線程應(yīng)用程序引起的恒削。
- 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命令輸出進(jìn)程的CPU占用率池颈,該命令會(huì)持續(xù)輸出,并且不會(huì)覆蓋之前的數(shù)據(jù)钓丰,可以方便觀察系統(tǒng)動(dòng)態(tài)躯砰。如上的輸出,可以看見兩個(gè)JAVA進(jìn)程占用了將近1600%的CPU時(shí)間携丁,既消耗了大約16個(gè)CPU核心的運(yùn)算資源琢歇。
- 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
iostat命令主要用于查看機(jī)器磁盤IO情況。該命令輸出的列梦鉴,主要含義是:
r/s, w/s, rkB/s, wkB/s:分別表示每秒讀寫次數(shù)和每秒讀寫數(shù)據(jù)量(千字節(jié))李茫。讀寫量過大,可能會(huì)引起性能問題肥橙。
await:IO操作的平均等待時(shí)間魄宏,單位是毫秒。這是應(yīng)用程序在和磁盤交互時(shí)存筏,需要消耗的時(shí)間娜庇,包括IO等待和實(shí)際操作的耗時(shí)。如果這個(gè)數(shù)值過大方篮,可能是硬件設(shè)備遇到了瓶頸或者出現(xiàn)故障名秀。
avgqu-sz:向設(shè)備發(fā)出的請求平均數(shù)量。如果這個(gè)數(shù)值大于1藕溅,可能是硬件設(shè)備已經(jīng)飽和(部分前端硬件設(shè)備支持并行寫入)匕得。
%util:設(shè)備利用率。這個(gè)數(shù)值表示設(shè)備的繁忙程度,經(jīng)驗(yàn)值是如果超過60汁掠,可能會(huì)影響IO性能(可以參照IO操作平均等待時(shí)間)略吨。如果到達(dá)100%,說明硬件設(shè)備已經(jīng)飽和考阱。如果顯示的是邏輯設(shè)備的數(shù)據(jù)翠忠,那么設(shè)備利用率不代表后端實(shí)際的硬件設(shè)備已經(jīng)飽和。值得注意的是乞榨,即使IO性能不理想秽之,也不一定意味這應(yīng)用程序性能會(huì)不好,可以利用諸如預(yù)讀取吃既、寫緩存等策略提升應(yīng)用性能考榨。
- 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
free命令可以查看系統(tǒng)內(nèi)存的使用情況,-m參數(shù)表示按照兆字節(jié)展示鹦倚。最后兩列分別表示用于IO緩存的內(nèi)存數(shù)河质,和用于文件系統(tǒng)頁緩存的內(nèi)存數(shù)。需要注意的是震叙,第二行-/+ buffers/cache掀鹅,看上去緩存占用了大量內(nèi)存空間。這是Linux系統(tǒng)的內(nèi)存使用策略媒楼,盡可能的利用內(nèi)存淫半,如果應(yīng)用程序需要內(nèi)存,這部分內(nèi)存會(huì)立即被回收并分配給應(yīng)用程序匣砖。因此科吭,這部分內(nèi)存一般也被當(dāng)成是可用內(nèi)存。
如果可用內(nèi)存非常少猴鲫,系統(tǒng)可能會(huì)動(dòng)用交換區(qū)(如果配置了的話)对人,這樣會(huì)增加IO開銷(可以在iostat命令中提現(xiàn)),降低系統(tǒng)性能拂共。
- 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
sar命令在這里可以查看網(wǎng)絡(luò)設(shè)備的吞吐率牺弄。在排查性能問題時(shí),可以通過網(wǎng)絡(luò)設(shè)備的吞吐量宜狐,判斷網(wǎng)絡(luò)設(shè)備是否已經(jīng)飽和势告。如示例輸出中,eth0網(wǎng)卡設(shè)備抚恒,吞吐率大概在22 Mbytes/s咱台,既176 Mbits/sec,沒有達(dá)到1Gbit/sec的硬件上限俭驮。
- 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
sar命令在這里用于查看TCP連接狀態(tài)回溺,其中包括:
active/s:每秒本地發(fā)起的TCP連接數(shù)春贸,既通過connect調(diào)用創(chuàng)建的TCP連接;
passive/s:每秒遠(yuǎn)程發(fā)起的TCP連接數(shù),即通過accept調(diào)用創(chuàng)建的TCP連接;
retrans/s:每秒TCP重傳數(shù)量;
TCP連接數(shù)可以用來判斷性能問題是否由于建立了過多的連接遗遵,進(jìn)一步可以判斷是主動(dòng)發(fā)起的連接萍恕,還是被動(dòng)接受的連接。TCP重傳可能是因?yàn)榫W(wǎng)絡(luò)環(huán)境惡劣车要,或者服務(wù)器壓力過大導(dǎo)致丟包允粤。
- 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命令包含了前面好幾個(gè)命令的檢查的內(nèi)容。比如系統(tǒng)負(fù)載情況(uptime)翼岁、系統(tǒng)內(nèi)存使用情況(free)类垫、系統(tǒng)CPU使用情況(vmstat)等。因此通過這個(gè)命令登澜,可以相對(duì)全面的查看系統(tǒng)負(fù)載的來源阔挠。同時(shí)飘庄,top命令支持排序脑蠕,可以按照不同的列排序,方便查找出諸如內(nèi)存占用最多的進(jìn)程跪削、CPU占用率最高的進(jìn)程等谴仙。
但是,top命令相對(duì)于前面一些命令碾盐,輸出是一個(gè)瞬間值晃跺,如果不持續(xù)盯著,可能會(huì)錯(cuò)過一些線索毫玖。這時(shí)可能需要暫停top命令刷新掀虎,來記錄和比對(duì)數(shù)據(jù)。
總結(jié)
排查Linux服務(wù)器性能問題還有很多工具付枫,上面介紹的一些命令烹玉,可以幫助我們快速的定位問題。例如前面的示例輸出阐滩,多個(gè)證據(jù)證明有JAVA進(jìn)程占用了大量CPU資源二打,之后的性能調(diào)優(yōu)就可以針對(duì)應(yīng)用程序進(jìn)行。
本人重新排版編輯簡書存檔掂榔,原文出處:http://www.codeceo.com/article/10-commands-linux-performance.html