登錄到一臺有性能問題的機器,第一步做什么?針對于面對性能問題無從下手,本文介紹性能查找方法論和快速定位問題的 10 個命令。
USE 方法
USE(Utilization Saturation and Errors)方法可以分析任何系統(tǒng)性能問題。它的思想就是根據(jù)一個 checklist, 一一核對,快速找到系統(tǒng)的錯誤和資源瓶頸。它旨在性能優(yōu)化早期發(fā)現(xiàn)系統(tǒng)問題。這些需要被檢查資源包括:
- CPUs : sockets, cores, hardware threads (virtual CPUs)
- Memory : capacity
- Network interfaces
- Storage devices : I/O, capacity
- Controllers : storage, network cards
- Interconnects : CPUs, memory, I/O
檢查每一個資源時,首先查看是否有錯誤產(chǎn)生,因為出現(xiàn)錯誤概率最大,其次是錯誤很容易被觀察到,不管是我們的軟件系統(tǒng)還是操作系統(tǒng)對錯誤都會有日志記錄。其次是使用率,如果使用率是 100%,那么一定是資源瓶頸,如果是 70%,這可能存在資源瓶頸問題。最后是飽和度,通常是一些排隊隊列的長度,如任務(wù)調(diào)度隊列長度,網(wǎng)絡(luò)發(fā)送隊列長度。通過檢查資源的出錯情況,使用率,飽和度往往能快速定位問題。值得注意的是,系統(tǒng)性能問題可能有多個原因。在著手性能分析第一步建議你使用以下 10 個命令來了解機器的使用情況,從一個比較高的層次去觀察機器。
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
uptime 命令幫助你快速查看系統(tǒng)的平均負(fù)載。敲下這個命令后分別顯示當(dāng)前時間,系統(tǒng)啟動時間,用戶數(shù),1 分鐘 5 分鐘 15 分鐘內(nèi)系統(tǒng)平均負(fù)載。平均負(fù)載可以理解成系統(tǒng)可運行的進程平均數(shù)。使用 3 個不同的時間粒度來幫助你分析系統(tǒng)負(fù)載的趨勢,例如判斷系統(tǒng)的是不是越來越大,還是已經(jīng)錯過了高峰。本例中,15 分鐘, 5 分鐘,1 分鐘系統(tǒng)的平均負(fù)載越來越大,說明系統(tǒng)的負(fù)載越來越大 。
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 條系統(tǒng)消息,你可以看看是否有錯誤產(chǎn)生,如上面這個例子出現(xiàn)了 out of memory 和 Dropping request 。如果 10 條內(nèi)容不夠可以使用 grep 進行搜索 或者使用 -n 參數(shù)查看更多。
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 是 Virtual Meomory Statistics(虛擬內(nèi)存統(tǒng)計)的縮寫,這條命令可對操作系統(tǒng)的虛擬內(nèi)存、進程、CPU 活動進行監(jiān)控。以參數(shù) 1 運行 ,1 秒鐘打印一次。參數(shù)說明如下
r:當(dāng)前運行隊列中線程的數(shù)目,r 值過大說明線程過多,就可能會出現(xiàn) CPU 瓶頸了;
b:等待 I/O 的進程數(shù)量;如果該值一直都很大,說明 I/O 比較繁忙,處理較慢;
swpd:虛擬內(nèi)存已使用的大小
free:空閑的物理內(nèi)存的大??;
buff:用作緩沖的內(nèi)存大小,這里指的是對磁盤的緩沖;
cache:用作緩存的內(nèi)存大?。蝗绻傅氖俏募到y(tǒng)的page cache
si: 每秒從交換區(qū)寫到內(nèi)存的大小
so: 每秒寫入交換區(qū)的內(nèi)存大小
bi:每秒讀取的塊數(shù);
bo:每秒寫入的塊數(shù);隨機磁盤讀寫的時候,這 2 個值越大,能看到 CPU 在 I/O 等待的值(io_wait)也會越大;
in:每秒中斷數(shù),包括時鐘中斷;
cs:每秒上下文切換數(shù);
us:用戶進程執(zhí)行時間(user time);
sy:系統(tǒng)進程執(zhí)行時間(system time);
id:空閑時間(idle 時間);
wa:等待 I/O 時間;wa 的值高時,說明 I/O 等待比較嚴(yán)重,這可能由于磁盤大量作隨機訪問造成,也有可能磁盤出現(xiàn)瓶頸。
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 的工作時間明細(xì),可用于檢查不平衡情況。 如果單 CPU 過熱,可能是單線程應(yīng)用程序造成的。vmstat 只能看到整體 CPU 使用情況, 而 mpstat 可以看到每個的 CPU 使用情況。
參數(shù) 釋義 從/proc/stat獲得數(shù)據(jù)
CPU 處理器ID
%usr 用戶態(tài)的 CPU 時間(%)
%nice nice 值為負(fù)進程的 CPU 時間(%)
%sys 內(nèi)核態(tài)的 CPU 時間(%)
%iowait 硬盤 I/O 等待時間(%)
%irq 硬中斷時間(%)
%soft 軟中斷時間(%)
%steal 顯示虛擬機管理器在服務(wù)另一個虛擬處理器時虛擬CPU處在非自愿等待下花費時間的百分比
%guest 顯示運行虛擬處理器時 CPU 花費時間的百分比
%gnice 顯示 niced guest 占比
%idle CPU 空閑等待時間(idle)(%)
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 命令。用來查看單個進程占用 CPU 的詳細(xì)情況。
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
iostat 是了解塊設(shè)備(磁盤)的工作負(fù)載以及所產(chǎn)生的性能的絕佳工具。參數(shù)釋義如下所示
%user:CPU 處在用戶模式下的時間百分比。%nice:用戶空間下高優(yōu)先級程序時間百分比。%system:CPU 處在內(nèi)核態(tài)下的時間百分比。%iowait:CPU 等待輸入輸出完成時間的百分比。%steal:管理程序維護另一個虛擬處理器時,虛擬 CPU 的無意識等待時間百分比。%idle:CPU 空閑時間百分比。
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
free 命令用來查看內(nèi)存使用情況。buffers 表示塊設(shè)備(磁盤)使用的緩存,而 cached 表示文件系統(tǒng)的頁緩存(page cache)
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
sar 是 System Activity Reporter(系統(tǒng)活動情況報告)的縮寫。sar 工具將對系統(tǒng)當(dāng)前的狀態(tài)進行取樣,然后通過計算數(shù)據(jù)和比例來表達系統(tǒng)的當(dāng)前運行狀態(tài)。它的特點是可以連續(xù)對系統(tǒng)取樣,獲得大量的取樣數(shù)據(jù);取樣數(shù)據(jù)和分析的結(jié)果都可以存入文件,所需的負(fù)載很小。sar 是目前 Linux 上最為全面的系統(tǒng)性能分析工具之一,可以從 14 個大方面對系統(tǒng)的活動進行報告,包括文件的讀寫情況、系統(tǒng)調(diào)用的使用情況、串口、CPU 效率、內(nèi)存使用狀況、進程活動及 IPC 有關(guān)的活動等。
這里參數(shù) DEV 是檢測網(wǎng)絡(luò)接口的吞吐:rxkB/s 和 txkB/s,作為收發(fā)數(shù)據(jù)負(fù)載的度量,也是檢測是否達到收發(fā)極限。在上面這個例子中,eth0 接收數(shù)據(jù)達到 22 M 字節(jié)/秒,也就是 176 Mbit/秒(網(wǎng)卡的上限是 1 Gbit/秒)。這個版本的工具還有一個統(tǒng)計字段: %ifutil,用于統(tǒng)計設(shè)備利用率(全雙工雙向最大值)。
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 關(guān)鍵指標(biāo)的統(tǒng)計,它包含了以下內(nèi)容:
- active/s:每秒本地發(fā)起的 TCP 連接數(shù)(例如通過 connect() 發(fā)起的連接)。
- passive/s:每秒遠(yuǎn)程發(fā)起的連接數(shù)(例如通過 accept() 接受的連接)。
- retrans/s:每秒 TCP 重傳數(shù)。
TCP 重傳是網(wǎng)絡(luò)或者服務(wù)器有問題的一個信號;可能是一個不可靠的網(wǎng)絡(luò)(例如:公網(wǎng)),或者可能是因為服務(wù)器過載了開始丟包。上面這個例子可以看出是每秒新建一個 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 命令用來查看系統(tǒng)各方面的資源使用情況。CPU,內(nèi)存等等。top 像 dashboard 一樣,數(shù)據(jù)是一直滾動刷新的。