# 練習 28:性能:獲取性能情況,`uptime`,`free`,`top`
> 原文:[Exercise 28. Performance: getting performance stats, uptime, free, top](https://archive.fo/U2SqV)
> 譯者:[飛龍](https://github.com/wizardforcel)
> 協議:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
> 自豪地采用[谷歌翻譯](https://translate.google.cn/)
這個練習很簡單。首先,我們需要什么樣的性能數據?
+ CPU 使用情況:
+ 它的負載如何?
+ 哪些進程正在使用它?
+ 內存使用情況:
+ 使用了多少內存?
+ 多少內存是空閑的?
+ 多少內存用于緩存?
+ 哪些進程消耗了它?
+ 磁盤使用情況:
+ 執行多少輸入/輸出操作?
+ 由哪個進程?
+ 網絡使用情況:
+ 傳輸了多少數據?
+ 由哪個進程?
+ 進程情況:
+ 有多少進程?
+ 他們在做什么 工作,還是等待什么?
+ 如果在等待什么,它是什么呢?CPU,磁盤,網絡?
為了獲取這些情況,我們可以使用以下工具:
+ `uptime` - 系統運行了多長時間。
+ `free` - 顯示系統中可用和使用的內存量。
+ `vmstat` - 進程,內存,分頁,塊 IO,陷阱,磁盤和 cpu 活動的信息。
+ `top` - 實時顯示 Linux 任務。
我們來看看這個程序及其輸出。
`uptime`的輸出:
```
user1@vm1:~$ uptime
#(1) (2) (3) (4) (5) (6)
03:13:58 up 4 days, 22:45, 1 user, load average: 0.00, 0.00, 0.00
```
字段和描述:
| 字段 | 描述 |
| --- | --- |
| (1) | 當前時間。 |
| (2) | 正常運行時間(啟動后的時間)。 |
| (3) | 目前有多少用戶登錄。 |
| (4) | 過去 1 分鐘的 CPU 負載。這不是規范化的,所以負載均值為 1 意味著單個 CPU 的滿負載,但是在 4 個 CPU 的系統上,這意味著它有 75% 空閑時間。 |
| (5) | 過去 5 分鐘的 CPU 負載。 |
| (6) | 過去 15 分鐘的 CPU 負載。 |
`free`的輸出:
```
user1@vm1:~$ free -mt
# (1) (2) (3) (4) (5) (6)
total used free shared buffers cached
Mem: 496 267 229 0 27 196
# (7) (8)
-/+ buffers/cache: 43 453
# 9
Swap: 461 0 461
# 10
Total: 958 267 691
```
字段和描述:
| 字段 | 描述 |
| --- | --- |
| (1) | 物理內存總量。 |
| (2) | 使用的物理內存總量。 |
| (3) | 空閑的物理內存總量。 |
| (4) | 共享內存列應該被忽略;它已經過時了。 |
| (5) | 專用于緩存磁盤塊的 RAM 和文件系統元數據總量。 |
| (6) | 專用于從文件讀取的頁面的 RAM 總量。 |
| (7) | 物理內存總量,不包括緩沖區和緩存,(2)-(5)-(6) |
| (8) | 空閑的物理內存總量,包括空閑的緩沖區和緩存,(1)-(7) |
| (9) | 交換文件使用信息。 |
| (10) | 總內存使用信息,包括交換內存 |
`vmstat`輸出:
```
user1@vm1:~$ vmstat -S M
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
#(1,2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12,13,14,15,16)
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 229 27 196 0 0 0 0 11 6 0 0 100 0
user1@vm1:~$ vmstat -S M -a
# (17) (18)
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free inact active si so bi bo in cs us sy id wa
0 0 0 11 434 19 0 0 24 2 11 6 0 0 100 0
user1@vm1:~$ vmstat -d
#19 (20) (21) (22) (23) (24) (25) (26) (27) (28) (29)
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
sda 11706 353 402980 17612 9303 40546 336358 46980 0 19
sr0 0 0 0 0 0 0 0 0 0 0
loop0 0 0 0 0 0 0 0 0 0 0
user1@vm1:~$ vmstat -m | head
#(30) (31) (32) (33) (34)
Cache Num Total Size Pages
ext3_inode_cache 13700 13700 808 10
ext3_xattr 0 0 88 46
journal_handle 170 170 24 170
journal_head 37 72 112 36
revoke_table 256 256 16 256
revoke_record 128 128 32 128
kmalloc_dma-512 8 8 512 8
ip6_dst_cache 16 24 320 12
UDPLITEv6 0 0 1024 8
```
字段和描述:
| 模式 | 情況 | 字段 | 描述 |
| --- | --- | --- | --- |
| 虛擬內存 | 進程 | (1) | r:等待運行的進程數。 |
| | | (2) | b:不間斷睡眠中的進程數。 |
| | 內存 | (3) | swpd:使用的虛擬內存量。 |
| | | (4) | free:空閑內存量。 |
| | | (5) | buff:用作緩沖區的內存量。 |
| | | (6) | cache:用作緩存的內存量。 |
| | | (17) | inact:非活動內存量。 |
| | | (18) | active:活動內存量。 |
| | 交換 | (7) | si:從磁盤換入的內存量(/秒)。 |
| | | (8) | so:換出到磁盤的內存量(/秒)。 |
| | I/O | (9) | bi:從設備接收的塊(塊/秒)。 |
| | | (10) | bo:發送到設備的塊(塊/秒)。 |
| | 系統 | (11) | in:每秒中斷的次數,包括時鐘。 |
| | | (12) | cs:每秒上下文切換的數量。 |
| | CPU | (13) | us:運行非內核代碼的時間。(用戶時間,包括優先的時間) |
| | | (14) | sy:運行內核代碼的時間。(系統時間) |
| | | (15) | id:閑置時間。在 Linux 2.5.41 之前,這包括 IO 等待時間。 |
| | | (16) | wa:IO 等待時間。在 Linux 2.5.41 之前,包含在閑置時間中。 |
| 磁盤,`-d` | 設備 | (19) | 設備名稱 |
| | 讀 | (20) | total:成功完成的總讀取數 |
| | | (21) | merge:分組的讀取數(生成一個 I/O) |
| | | (22) | sectors:成功讀取的分區 |
| | | (23) | ms:用于讀取的毫秒 |
| | 寫 | (24) | total:成功完成的總寫入數 |
| | | (25) | merge:分組的寫入數(生成一個 I/O) |
| | | (26) | sectors:成功寫入的分區 |
| | | (27) | ms:用于寫入的毫秒 |
| | I/O | (28) | cur:正在進行中的 I/O |
| | | (29) | s:用于 I/O 的秒數 |
| Slab,`-m` | Slab | (30) | 緩存:緩存名稱 |
| | | (31) | num:當前活動對象的數量 |
| | | (32) | total:可用對象的總數 |
| | | (33) | size:每個對象的大小 |
| | | (34) | page:具有至少一個活動對象的頁數 |
`top`的輸出:
```
# (1) (2) (3) (4)
top - 03:22:44 up 4 days, 22:54, 1 user, load average: 0.00, 0.00, 0.00
# (5) (6) (7) (8) (9)
Tasks: 63 total, 1 running, 62 sleeping, 0 stopped, 0 zombie
# (10) (11) (12) (13) (14) (15) (16) (17)
Cpu(s): 0.0%us, 1.1%sy, 0.0%ni, 98.9%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
# (18) (19) (20) (21)
Mem: 508820k total, 273792k used, 235028k free, 27844k buffers
# (22) (23) (24) (25)
Swap: 473080k total, 0k used, 473080k free, 201252k cached
#(26) (27) (28)(29) (30) (31) (32,33) (34)(35) (36) (37)
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 8356 804 676 S 0.0 0.2 0:05.99 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
4 root 20 0 0 0 0 S 0.0 0.0 0:00.06 ksoftirqd/0
5 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
6 root 20 0 0 0 0 S 0.0 0.0 0:03.25 events/0
7 root 20 0 0 0 0 S 0.0 0.0 0:00.00 cpuset
<...>
```
字段和輸出:
| 部分 | 字段 | 描述 |
| --- | --- | --- |
| 正常運行時間 | (1) | 當前時間。 |
| | (2) | 正常運行時間(啟動后的時間)。 |
| | (3) | 目前有多少用戶登錄。 |
| | (4) | 過去 1,5 和 15 分鐘內的 CPU 負載。這不是規范化的,所以負載均值為 1 意味著單個 CPU 的滿負載,但是在 4 個 CPU 的系統上,這意味著它有 75% 空閑時間。 |
| 任務 | (5) | 運行進程總數。 |
| | (6) | 當前正在執行的進程數。 |
| | (7) | 當前正在睡眠的進程數。 |
| | (8) | 被停止的進程數(例如使用`CTRL + Z`)。 |
| | (9) | 已經停止(“僵尸”)的進程數量,已終止,但未由其父進程回收。 |
| CPU(S) | (10) | CPU 運行不優先的用戶進程的時間。 |
| | (11) | CPU 運行內核及其進程的時間。 |
| | (12) | CPU 運行優先的用戶進程的時間。 |
| | (13) | CPU 花費的空閑時間。 |
| | (14) | CPU 等待 I/O 完成的時間。 |
| | (15) | CPU 維護硬件中斷的時間。 |
| | (16) | CPU 維護軟件中斷的時間。 |
| | (17) | 由管理程序從這個虛擬機“偷走”的 CPU 總量,用于其他任務(例如啟動另一個虛擬機)。 |
| 內存/交換 | (18) | 物理內存總量。 |
| | (19) | 使用的物理內存總量。 |
| | (20) | 完全空閑的物理內存。 |
| | (21) | 專用于緩存磁盤塊的 RAM 和文件系統元數據總量。 |
| | (22,23,24) | 總,使用和空閑交換內存。 |
| | (25) | 專用于從文件讀取的頁面的 RAM 總量。 |
| 進程 | (26) | 任務的唯一進程 ID,它定期地包裝,盡管從未重新啟動。 |
| | (27) | 任務所有者的有效用戶名。 |
| | (28) | 任務的優先級。 |
| | (29) | 任務的優先值。負的優先值表示更高的優先級,而正的優先值表示較低的優先級。在這個字段中的零只是代表在確定任務的調度時不會調整優先級。 |
| | (30) | 任務使用的虛擬內存總量。它包括所有代碼,數據和共享庫,以及已經被替換的頁面。以及已被映射但未被使用的頁面。 |
| | (31) | 任務已使用的未交換的物理內存。 |
| | (32) | 任務使用的共享內存量。它只是反映可能與其他進程共享的內存。 |
| | (33) | 任務的狀態可以是以下之一:`D`=不間斷睡眠,`R`=運行,`S`=睡眠,`T`=跟蹤或停止,`Z`=僵尸。 |
| | (34) | 自上次屏幕更新以來,所經過的 CPU 時間的任務份額,以 CPU 時間總數的百分比表示。 |
| | (35) | 任務當前使用的可用物理內存的份額。 |
| | (36) | CPU 時間,單位是百分之一秒,與`TIME`相同,但通過百分之一秒反映更大的粒度。 |
| | (37) | 命令 - 命令行或程序名稱 |
你可能會看到很多字段。許多字段都存在于多個工具中,這些工具有些冗余的功能。通常情況下,你只需要這個字段的一小部分,但你需要知道,系統性能的許多信息(實際上還有更多)可用于你,因為有時候會出現一個模糊的問題,并且為了能夠解決它,需要知道如何讀取這些數據。
現在,你將學習如何使用系統性能工具。
## 這樣做
```
1: uptime
2: free
3: vmstat
4: ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 && killall vmstat )& vmstat 1
5: uptime
6: ( sleep 5 && dd if=/dev/zero of=test.img bs=32 count=$((32*1024*200)) && sleep 5 && killall vmstat )& vmstat -nd 1 | egrep -v 'loop|sr0'
7: echo 3 | sudo tee /proc/sys/vm/drop_caches
8: free -mt ; find / >/dev/null 2>&1 ; free -mt
9: echo 3 | sudo tee /proc/sys/vm/drop_caches
10: cat test.img /dev/null ; free -mt
```
## 你會看到什么
```
user1@vm1:~$ uptime
05:36:45 up 6 days, 1:08, 1 user, load average: 0.00, 0.00, 0.00
user1@vm1:~$ free
total used free shared buffers cached
Mem: 508820 239992 268828 0 820 213720
-/+ buffers/cache: 25452 483368
Swap: 473080 0 473080
user1@vm1:~$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 268828 820 213720 0 0 21 10 14 11 0 0 100 0
user1@vm1:~$ ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 && killall vmstat )& vmstat 1
[1] 6078
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 1 0 268556 828 213736 0 0 21 10 14 11 0 0 100 0
0 0 0 268556 828 213772 0 0 16 0 19 10 0 0 100 0
0 0 0 268556 828 213772 0 0 0 0 13 8 0 0 100 0
0 0 0 268556 828 213772 0 0 0 0 15 11 0 0 100 0
0 0 0 268556 828 213772 0 0 0 0 14 10 0 0 100 0
0 0 0 268556 828 213772 0 0 0 0 18 13 0 0 100 0
1 0 0 267316 836 213844 0 0 74 0 267 26 0 99 1 0
1 0 0 267316 836 213844 0 0 0 0 303 7 0 100 0 0
1 0 0 267316 836 213844 0 0 0 0 271 11 0 100 0 0
1 0 0 267316 836 213844 0 0 0 0 257 12 0 100 0 0
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 4.95038 s, 6.4 MB/s
0 0 0 267928 860 213860 0 0 27 0 265 29 1 97 2 0
0 0 0 267936 860 213848 0 0 0 0 15 9 0 0 100 0
0 0 0 267936 860 213848 0 0 0 0 14 7 0 0 100 0
0 0 0 267936 860 213848 0 0 0 0 14 7 0 0 100 0
0 0 0 267936 860 213848 0 0 0 0 13 11 0 0 100 0
Terminated
user1@vm1:~$ uptime
05:22:15 up 6 days, 54 min, 1 user, load average: 0.07, 0.02, 0.00
[1]+ Done ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 && killall vmstat )
user1@vm1:~$ uptime
05:22:22 up 6 days, 54 min, 1 user, load average: 0.06, 0.02, 0.00
user1@vm1:~$ ( sleep 5 && dd if=/dev/zero of=test.img bs=32 count=$((32*1024*200)) && sleep 5 && killall vmstat )& vmstat -nd 1 | egrep -v 'loop|sr0'
[1] 6086
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
sda 146985 2230744 21821320 105848 32190 1343154 10927338 1330144 0 105
sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144 0 105
sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144 0 105
sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144 0 105
sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144 0 105
sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144 0 105
sda 146999 2230744 21821680 105856 32190 1343154 10927338 1330144 0 105
sda 146999 2230744 21821680 105856 32190 1343154 10927338 1330144 0 105
sda 147000 2230744 21821688 105856 32208 1344160 10935530 1330288 0 105
sda 147000 2230744 21821688 105856 32274 1349214 10976490 1330748 0 105
sda 147000 2230744 21821688 105856 32325 1353259 11009258 1331236 0 105
sda 147000 2230744 21821688 105856 32450 1364657 11101442 1337176 0 105
sda 147000 2230744 21821688 105856 32450 1364657 11101442 1337176 0 105
sda 147001 2230744 21821696 105856 32471 1366301 11114762 1337348 0 105
sda 147001 2230744 21821696 105856 32525 1370529 11149018 1337732 0 105
sda 147001 2230744 21821696 105856 32573 1374577 11181786 1338064 0 105
sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244 0 105
6553600+0 records in
6553600+0 records out
209715200 bytes (210 MB) copied, 11.7088 s, 17.9 MB/s
sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244 0 105
sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244 0 105
sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244 0 105
sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244 0 105
sda 147001 2230744 21821696 105856 32762 1393910 11337962 1349192 0 105
user1@vm1:~$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
[1]+ Done ( sleep 5 && dd if=/dev/zero of=test.img bs=32 count=$((32*1024*200)) && sleep 5 && killall vmstat )
user1@vm1:~$ free -mt ; find / >/dev/null 2>&1 ; free -mt
total used free shared buffers cached
Mem: 496 30 466 0 0 5
-/+ buffers/cache: 24 472
Swap: 461 0 461
Total: 958 30 928
total used free shared buffers cached
Mem: 496 64 432 0 22 6
-/+ buffers/cache: 35 461
Swap: 461 0 461
Total: 958 64 894
user1@vm1:~$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
user1@vm1:~$ cat test.img /dev/null ; free -mt
total used free shared buffers cached
Mem: 496 230 265 0 0 205
-/+ buffers/cache: 24 471
Swap: 461 0 461
Total: 958 230 727
user1@vm1:~$
```
## 解釋
1. 打印當前的正常運行時間。
1. 打印出可用內存信息。
1. 這個很有趣,最好認為是一種實驗。首先,我們在后臺啟動` ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 && killall vmstat )&`,之后我們 以連續模式啟動`vmstat`,所以它將打印出其信息直到中斷。我們可以看到,在這個命令啟動 5 秒鐘后,CPU 負載顯著增加了一段時間,然后減少,另外 5 秒鐘后`vmstat`被殺死。
1. 打印當前的正常運行時間。注意負載平均值的變化。
1. 這是另一個實驗,幾乎和以前一樣,但這次用磁盤寫入。
1. 刪除所有緩存和緩沖區。
1. 另一個實驗。我們想看看讀取系統中的所有文件和目錄名稱,會如何影響內存中的文件系統緩存,并且我們可以看到它被緩存在緩沖區中,這是有理論根據的。
1. 再次刪除所有緩存和緩沖區。
1. 這次我們想看看,文件讀取如何影響內存中的文件系統緩存。我們可以看到讀取的文件被緩存在緩存部分,來增加后續訪問的時間。
## 附加題
+ 為什么在我們的第一個實驗中,不是`user`,而是`system` CPU 使用率上升到 100?
+ 這是什么意思?`dd if=/dev/zero of=test.img bs=32 count=$( (32*1024*200) )`。
+ 啟動`top`,并按下`h`。現在嘗試按照 CPU,內存和 PID 對其輸出進行排序。
- 笨辦法學 Linux 中文版
- 練習 0:起步
- 練習 1:文本編輯器,vim
- 練習 2:文本瀏覽器,少即是多
- 練習 3:Bash:Shell、.profile、.bashrc、.bash_history
- 練習 4:Bash:處理文件,pwd,ls,cp,mv,rm,touch
- 練習 5:Bash:環境變量,env,set,export
- 練習 6:Bash:語言設置,LANG,locale,dpkg-reconfigure locales
- 練習 7:Bash:重定向,stdin,stdout,stderr,<,>,>>,|,tee,pv
- 練習 8:更多的重定向和過濾:head,tail,awk,grep,sed
- 練習 9:Bash:任務控制,jobs,fg
- 練習 10:Bash:程序退出代碼(返回狀態)
- 練習 11:總結
- 練習 12:文檔:man,info
- 練習 13:文檔:Google
- 練習 14:包管理:Debian 包管理工具aptitude
- 練習 15:系統啟動:運行級別,/etc/init.d,rcconf,update-rc.d
- 練習 16:處理進程,ps,kill
- 練習 17:任務調度:cron,at
- 練習 18:日志:/var/log,rsyslog,logger
- 練習 19:文件系統:掛載,mount,/etc/fstab
- 練習 20:文件系統:修改和創建文件系統,tune2fs,mkfs
- 練習 21:文件系統:修改根目錄,chroot
- 練習 22:文件系統:移動數據,tar,dd
- 練習 23:文件系統:權限,chown,chmod,umask
- 練習 24:接口配置,ifconfig,netstat,iproute2,ss,route
- 練習 25:網絡:配置文件,/etc/network/interfaces
- 練習 26:網絡:封包過濾配置,iptables
- 練習 27:安全 Shell,ssh,sshd,scp
- 練習 28:性能:獲取性能情況,uptime,free,top
- 練習 29:內核:內核消息,dmesg
- 練習 30:打磨、洗練、重復:總復習
- 下一步做什么
- Debian 手動安裝