前言
Linux下的top命令我相信大家都用過,自從我接觸Linux以來就一直用top檢視程式的CPU和MEM排行榜。但是top命令的其他輸出結果我都沒有了解,這些指標都代表什麼呢,什麼情況下需要關注呢?以及top命令輸出結果的來源資料是什麼呢,又是怎麼一個計算原理呢?
演示環境
# uname -a Linux VM_1_11_centos 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
top命令
top命令是Linux下常用的效能分析工具,能夠實時(預設是3s重新整理一次)的顯示系統的資源使用情況,以及各種程式的資源使用情況,類似於Windows的工作管理員。
top - 11:00:54 up 54 days, 23:35, 6 users, load average: 16.32, 18.75, 21.04 Tasks: 209 total, 3 running, 205 sleeping, 0 stopped, 1 zombie %Cpu(s): 29.7 us, 18.9 sy, 0.0 ni, 49.3 id, 1.7 wa, 0.0 hi, 0.4 si, 0.0 st KiB Mem : 32781216 total, 1506220 free, 6525496 used, 24749500 buff/cache KiB Swap: 0 total, 0 free, 0 used. 25607592 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 23444 root 20 0 15.6g 461676 4704 R 198.0 1.4 11:15.26 python 16729 root 20 0 9725596 240028 4672 R 113.0 0.7 7:48.49 python 3388 root 20 0 6878028 143196 4720 S 82.4 0.4 1:35.03 python
第一行資料相當於uptime命令輸出。11:00:54是當前時間,up 54 days,23:55 是系統已經執行的時間,6 users表示當前有6個使用者在登入,load average:16.32,18.75,21.04分別表示系統一分鐘平均負載,5分鐘平均負載,15分鐘平均負載。
平均負載
平均負載表示的平均活躍程式數,包括正在running的程式數,準備running(就緒態)的程式數,和處於不可中斷睡眠狀態的程式數。如果平均負載數剛好等於CPU核數,那證明每個核都能得到很好的利用,如果平均負載數大於核數證明系統處於過載的狀態,通常認為是超過核數的70%認為是嚴重過載,需要關注。還需結合1分鐘平均負載,5分鐘平均負載,15分鐘平均負載看負載的趨勢,如果1分鐘負載比較高,5分鐘和15分鐘的平均負載都比較低,則說明是瞬間升高,需要觀察。如果三個值都很高則需要關注下是否某個程式在瘋狂消耗CPU或者有頻繁的IO操作,也有可能是系統執行的程式太多,頻繁的程式切換導致。比如說上面的演示環境是一臺8核的centos機器,證明系統是長期處於過載狀態在執行。
Tasks: 214 total, 4 running, 209 sleeping, 0 stopped, 1 zombie
第二行的Tasks資訊展示的系統執行的整體程式數量和狀態資訊。214 total 表示系統現在一共有214個使用者程式,4 running 表示4個程式正在處於running狀態,209 sleeping表示209個程式正處於sleeping狀態,0 stopped 表示 0 個程式正處於stopped狀態,1 zombie表示 有1個殭屍程式。
殭屍程式
子程式結束時父程式沒有呼叫wait()/waitpid()等待子程式結束,那麼就會產生殭屍程式。原因是子程式結束時並沒有真正退出,而是留下一個殭屍程式的資料結構在系統程式表中,等待父程式清理,如果父程式已經退出則會由init程式接替父程式進行處理(收屍)。由此可見,如果父程式不作為並且又不退出,就會有大量的殭屍程式,每個殭屍程式會佔用程式表的一個位置(slot),如果殭屍程式太多會導致系統無法建立新的程式,因為程式表的容量是有限的。所以當zombie這個指標太大時需要引起我們的注意。下面的程式詳細資訊中的S列就代表程式的執行狀態,Z表示該程式是殭屍程式。
消滅殭屍程式的方法:
1.找到殭屍程式的父程式pid(pstress可以顯示程式父子關係),kill -9 pid,父程式退出後init自動會清理殭屍程式。(需要注意的是kill -9並不能殺死殭屍程式)
2.重啟系統。
%Cpu(s): 31.9 us, 30.3 sy, 0.0 ni, 37.0 id, 0.0 wa, 0.0 hi, 0.8 si, 0.0 st
第三行的%Cpu(s)表示的是總體CPU使用情況。
- us user 表示使用者態的CPU時間比例
- sy system 表示核心態的CPU時間比例
- ni nice 表示執行低優先順序程式的CPU時間比例
- id idle 表示空閒CPU時間比例
- wa iowait 表示處於IO等待的CPU時間比例
- hi hard interrupt 表示處理硬中斷的CPU時間比例
- si soft interrupt 表示處理軟中斷的CPU時間比例
- st steal 表示當前系統執行在虛擬機器中的時候,被其他虛擬機器佔用的CPU時間比例。
所以整體的CPU使用率=1-id。當us很高時,證明CPU時間主要消耗在使用者程式碼,需要優化使用者程式碼。sy很高時,說明CPU時間都消耗在核心,要麼是頻繁的系統呼叫,要麼是頻繁的CPU切換(程式切換/執行緒切換)。wa很高時,說明有程式在程式頻繁的IO操作,有可能是磁碟IO,也有可能是網路IO。si很高時,說明CPU時間消耗在處理軟中斷,網路收發包會觸發系統軟中斷,所以大量的網路小包會導致軟中斷的頻繁觸發,典型的SYN Floor會導致si很高。
KiB Mem : 32781216 total, 663440 free, 7354900 used, 24762876 buff/cache KiB Swap: 0 total, 0 free, 0 used. 24771700 avail Mem
第4,5行顯示的是系統記憶體使用情況。單位是KiB。totol 表示總記憶體,free 表示沒使用過的內容,used是已經使用的記憶體。buff表示用於讀寫磁碟快取的記憶體,cache表示用於讀寫檔案快取的記憶體。avail表示可用的應用記憶體。
Swap原理是把一塊磁碟空間或者一個本地檔案當成記憶體來使用。Swap total表示能用的swap總量,swap free表示剩餘,used表示已經使用的。這三個值都為0表示系統關閉了swap功能,由於演示環境是一臺虛擬機器,虛擬機器一般都關閉swap功能。
第6行開始往後表示的是具體的每個程式狀態:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
- PID 程式ID
- USER 程式所有者的使用者名稱,例如root
- PR 程式排程優先順序
- NI 程式nice值(優先順序),越小的值代表越高的優先順序
- VIRT 程式使用的虛擬記憶體
- RES 程式使用的實體記憶體(不包括共享記憶體)
- SHR 程式使用的共享記憶體
- CPU 程式使用的CPU佔比
- MEM 程式使用的記憶體佔比
- TIME 程式啟動後到現在所用的全部CPU時間
- COMMAND 程式的啟動命令(預設只顯示二進位制,top -c能夠顯示命令列和啟動引數)
計算原理
在介紹top命令的各項指標計算原理之前,有必要先介紹下Linux下的proc檔案系統,因為top命令的各項資料來源於proc檔案系統。proc檔案系統是一個虛擬的檔案系統,是Linux核心和使用者的一種通訊方式,Linux核心會通過proc檔案系統告訴使用者現在核心的狀態資訊,使用者也可以通過寫proc的方式設定核心的一些行為。與普通檔案不同的是,這些proc檔案是動態建立的,也是動態修改的,因為核心的狀態時刻都在變化。
top顯示的CPU指標都是來源於/proc/stat檔案資訊:
# cat /proc/stat cpu 1151829380 20277 540128095 1909004524 21051740 0 10957596 0 0 0 cpu0 143829475 3918 67658924 235696976 5168514 0 1475030 0 0 0 cpu1 144407338 1966 67616825 236756510 3969110 0 1392212 0 0 0 cpu2 144531920 2287 67567520 238021699 2713175 0 1363460 0 0 0 cpu3 143288938 2366 67474485 239715220 2223739 0 1356698 0 0 0 cpu4 143975390 3159 67394206 239494900 1948424 0 1343261 0 0 0 cpu5 144130685 2212 67538520 239431294 1780756 0 1349882 0 0 0 cpu6 144009592 2175 67536945 239683876 1668203 0 1340087 0 0 0 cpu7 143656038 2193 67340668 240204045 1579816 0 1336963 0 0 0
第一行代表的總的CPU資訊,後面的是一個CPU的詳細資訊。
但是這些具體的後面的列都是什麼資訊呢,我們可以通過man proc找到答案:
user (1) Time spent in user mode. nice (2) Time spent in user mode with low priority (nice). system (3) Time spent in system mode. idle (4) Time spent in the idle task. This value should be USER_HZ times the second entry in the /proc/uptime pseudo-file. iowait (since Linux 2.5.41)
(5) Time waiting for I/O to complete. irq (since Linux 2.6.0-test4) (6) Time servicing interrupts. softirq (since Linux 2.6.0-test4) (7) Time servicing softirqs. steal (since Linux 2.6.11) (8) Stolen time, which is the time spent in other operating systems when running in a virtual‐ ized environment guest (since Linux 2.6.24) (9) Time spent running a virtual CPU for guest operating systems under the control of the Linux kernel. guest_nice (since Linux 2.6.33) (10) Time spent running a niced guest (virtual CPU for guest operating systems under the con‐ trol of the Linux kernel).
也就是說從第二列開始往後分別是user,nice,system,idle,iowait,irq(硬中斷),softirq(軟中斷),steal,guest,guest_nice的CPU時間,單位通常是10ms。那麼top裡面的比例又是怎麼算出的呢?
由於CPU時間是一個累加值,所以我們要求一個時間段差值來反映當前的CPU情況,top預設是3s。例如現在取一個user值user1,和當前的一個總量的CPU時間total1
其中total等於上面各項相加,也就是total=user+nice+system+idle+iowait+irq+softirq+steal+guest+guest_nice。3秒後再去一個user值user2和一個總量total2。
那麼這3秒鐘的user平均cpu佔比就等於((user2-user1)/ (total2-total1))/ 3 * 100%。另外每個具體的CPU計算方式同理。
top記憶體相關的指標直接讀取/proc/meminfo檔案的對應欄位:
# cat /proc/meminfo MemTotal: 32781216 kB MemFree: 1043556 kB MemAvailable: 25108920 kB Buffers: 427516 kB Cached: 22084612 kB SwapCached: 0 kB Active: 18640888 kB Inactive: 10534920 kB Active(anon): 6664480 kB Inactive(anon): 412 kB Active(file): 11976408 kB Inactive(file): 10534508 kB Unevictable: 4 kB Mlocked: 4 kB SwapTotal: 0 kB SwapFree: 0 kB Dirty: 1092 kB Writeback: 0 kB AnonPages: 6663764 kB Mapped: 347808 kB Shmem: 1212 kB Slab: 2201292 kB SReclaimable: 1957344 kB SUnreclaim: 243948 kB KernelStack: 73392 kB PageTables: 57300 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 16390608 kB Committed_AS: 42170784 kB VmallocTotal: 34359738367 kB VmallocUsed: 61924 kB VmallocChunk: 34359625048 kB HardwareCorrupted: 0 kB AnonHugePages: 364544 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 376680 kB DirectMap2M: 26886144 kB DirectMap1G: 8388608 kB
其中total對應於MemTotal,free 對應於MemFree,avail 對應於MemAailable。
總結
文章從top命令的輸出結果開始,說明哪些指標的異常值需要我們關注,最後介紹了top命令的cpu計算原理和mem的資料來源。