此文已由作者牛小寶授權網易雲社區發布。

歡迎訪問網易雲社區,了解更多網易技術產品運營經驗。

在進行服務端性能測試時,需要觀察系統對CPU的使用情況,以此作為衡量整個系統性能的重要指標,對於Linux CPU主要的關注點在利用率,運行隊列,負載,上下文切換等,因此了解這些指標的含義和常用的監控方法對性能測試又很大的幫助。

1、CPU使用率

Linux CPU使用率主要是從以下幾個維度進行統計:

  • %usr:普通進程在用戶模下下執行的時間;
  • %sys:進程在內核模式下的執行時間;
  • %nice:被提高優先順序的進程在用戶模式下的執行時間;
  • %idle:空閑時間。
  • %iowait:等待I/O完成的時間。
  • %irp:處理硬中斷請求花費的時間。
  • %soft:處理軟中斷請求花費的時間。
  • %steal:是衡量虛擬機CPU的指標,是指分配給本虛擬機的時間片被同一宿主機別的虛擬機佔用,一般%steal值較高時,說明宿主機的資源使用已達到瓶頸;

一般情況下,CPU大部分的時間片都是消耗在用戶態和內核態上,sys和user間的比例是相互影響的,%sys比例高意味著被測服務頻繁的進行用戶態和系統態之間的切換,會帶來一定的CPU開銷,這樣分配處理業務的時間片就會較少,造成系統性能的下降。對於IO密集型系統,無論是網路IO還是磁碟IO,一般都會產生大量的中斷,從而導致%sys相對升高,其中磁碟IO密集型系統,對磁碟的讀寫需要佔用大量的CPU,會導致%iowait的值一定比例的升高,所以當出現%iowait較高時,需排查是否存在大量的不合理的日誌操作,或者頻繁的數據載入等情況;

CPU利用的詳細情況可以通過top,vmstat命令進行查看

  • top:

%Cpu(s): 0.9 us, 0.6 sy, 0.0 ni, 98.4 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st

  • vmstat:

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 1061592 15986 395216 91660 0 0 3 9 0 0 5 1 94 0

  • mpstat:

CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
all 0.92 0.00 0.50 0.17 0.00 0.00 0.00 4.14 94.27

2、運行隊列:

當Linux內核要尋找一個新的進程在CPU上運行時,必須只考慮處於可運行狀態的進程,(即在TASK_RUNNING狀態的進程),因為掃描整個進程鏈表是相當低效的,所以引入了可運行狀態進程的雙向循環鏈表,也叫運行隊列(runqueue)。每個CPU或者說每個核都會維持一個運行隊列,隊列中存放running和runnable兩種狀態的進程,CPU會不斷的調度隊列中的進程運行,因此隊列中的進程數越多,每個進程分別到的時間片就越少,程序的時間也就越長,同時CPU會不斷的處於運行狀態,性能開銷較大。可以通過觀察一定時間內運行隊列中的進程數量來判斷CPU是否達到的瓶頸,這就有了負載的概念;

3、負載:

CPU的負載(Load),是指在一段時間內 CPU正在處理以及等待 CPU處理的進程數之和的統計信息,也就是 CPU運行隊列長度的統計信息。平均負載(Load Average)是指上一段時間內同時處於運行隊列的平均進程數,Load Average是反應系統壓力的重要指標,Load Average越高說明對於CPU資源的競爭越激烈,CPU資源比較短缺。對於資源的申請和維護其實也是需要很大的成本,所以在這種高Average Load的情況下CPU資源的長期「熱競爭」也是對於硬體的一種損害。

舉個例子,把CPU處理進程的過程看成火車站售票:

  • 假如售票處有10個窗口,買票的人只有1個,毫無疑問,這個乘客隨便找個窗口買完票就可以拍屁股走人了,而且還有9個售票人員可以喝茶看報紙,這時的平均負載是0.1,售票運作毫無壓力;
  • 如果買票的人有10個,那也還好,一個窗口一個人,所有窗口的售票人員都在工作,也可以快速的買到票,這時的平均負載是1,所有的售票窗口都在運作;
  • 如果有20個人在買票,這就要出現排隊的情況,售票人員要不停的賣票,直到排隊的都買到票,這時平均負載是2,所有售票窗口都在運作,而且出現了排隊情況;

如果是100,200人或者更多的人買票,這時售票人員就要不停的工作,為了不把售票人員累壞可能就要考慮增加窗口,也就是擴容了。而實際CPU處理進程時並不是像售票一樣賣完一個人下一個人,CPU處理每個進程時是有固定的時間片,如果在時間片內這個任務沒有處理完,就要掛起這個任務處理下一個,這是就會產生中斷,高負載的情況下會不斷產生進程間的調用,從而產生大量中斷,造成系統的開銷,所以在做性能測試時,要重點關注負載情況,來判讀CPU是否達到了瓶頸,依據經驗分析,單核CPU負載<2時,系統性能是良好的,當單核CPU負載>5時,那麼就表明這個機器存在嚴重的性能問題。

負載可以通過top,uptime、cat /proc/loadavg等命令查看1分鐘,5分鐘,15分鐘的負載值:
  • top

top - 10:45:06 up 406 days, 7:29, 5 users, load average: 0.35, 0.63, 0.54

  • uptime

10:45:23 up 406 days, 7:30, 5 users, load average: 0.27, 0.60, 0.53

  • cat /proc/loadavg

0.21 0.57 0.52 2/530 32089

4、上下文切換

一個標準的Linux內核可以支持運行50~50000個進程運行,對於普通的CPU,內核會調度和執行這些進程。每個進程都會分到CPU的時間片來運行,當一個進程用完時間片或者被更高優先順序的進程搶佔後,它會備份到CPU的運行隊列中,同時其他進程在CPU上運行。這個進程切換的過程被稱作上下文切換。Linux系統具有兩個不同級別的運行模式,內核態和用戶態,其中內核態的運行級別要大於用戶態,這個級別可以進行任何操作,一般內核運行與內核態,而應用程序是運行在用戶態。當發生上下文切換時,通過系統調用,處於用戶態的應用程序就會進入內核空間,待調用完成之後重新返回值用戶態運行,因此上下文切換存在系統開銷,會一定程度上增加%sys的值。

當一個進程在執行時,CPU的所有寄存器中的值、進程的狀態以及堆棧中的內容被稱為該進程的上下文。當內核需要切換到另一個進程時,它需要保存當前進程的所有狀態,即保存當前進程的上下文,以便在再次執行該進程時,能夠必得到切換時的狀態執行下去。在LINUX中,當前進程上下文均保存在進程的任務數據結構中。在發生中斷時,內核就在被中斷進程的上下文中,在內核態下執行中斷服務常式。但同時會保留所有需要用到的資源,以便中斷服務結束時能恢復被中斷進程的執行。

引起上下文切換的原因有哪些? 對於搶佔式操作系統而言, 大體有幾種:

  1. 當前任務的時間片用完之後,系統CPU正常調度下一個任務;
  2. 當前任務碰到IO阻塞,調度線程將掛起此任務,繼續下一個任務;
  3. 多個任務搶佔鎖資源,當前任務沒有搶到,被調度器掛起,繼續下一個任務;
  4. 用戶代碼掛起當前任務,讓出CPU時間;
  5. 硬體中斷;

vmstat中的cs為中斷數量

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 54484 343748 687816 45583564 0 0 1 3 0 0 1 0 99 0

5、中斷

中斷是指CPU執行程序時,由於發生了某種隨機的事件(外部或內部),引起CPU暫時中斷正在運行的程序,轉去執行一段特殊的服務程序(稱為中斷服務程序或中斷處理程序),以處理該事件,該事件處理完後又返回被中斷的程序繼續執行。引入中斷的原因有以下幾點:

  1. 提高數據傳輸率;
  2. 避免了CPU不斷檢測外設狀態的過程,提高了CPU的利用率。
  3. 實現對特殊事件的實時響應。如多任務系統操作系統中缺頁中斷、設備中斷、各類異常、實時鐘等

中斷根據中斷源的不同可以分為硬中斷和軟中斷:

  • 硬中斷: 硬中斷又稱外部中斷,是由硬體產生,如鍵盤,滑鼠,印表機等。每個設備或設備集都有它自己的中斷請求(IRQ),基於IRQ,CPU可以將相應的請求分發到對應的硬體驅動上,處理中斷的驅動是需要在CPU上運行的,因此中斷產生時,CPU會中斷當前正在運行的任務來處理中斷,在多核的操作系統中,一個中斷通常只能中斷一顆CPU(核)。
  • 軟中斷: 軟中斷又稱內部中斷,由軟體系統本身發給操作系統內核的中斷信號。通常是由硬中斷處理程序或進程調度程序對操作系統內核的中斷,也就是我們常說的系統調用(System Call)。一般情況下軟中斷是處理I/O請求時發生訂單,這些請求會調用內核中的處理I/O的程序,對於某些設備,I/O請求需要被立即處理,而磁碟I/O請求通常可以排隊並且可以稍後處理。根據I/O模型的不同,進程或許會被掛起直到I/O完成,此時內核調度器就會選擇另一個進程去運行。I/O可以在進程之間產生並且調度過程通常和磁碟I/O的方式是相同。在I/O密集型系統中可能會出現大量的中斷請求,中斷會產生中斷上下文,造成CPU開。

可以通過top,vmstat等查看CPU的相關命令中監控中斷情況

  • vmstat中的in為中斷數量

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 54484 343748 687816 45583564 0 0 1 3 0 0 1 0 99 0

  • mpstat中的 %irq %soft分別為硬中斷和軟中斷所佔CPU時間片比例

Linux 3.2.0-3-amd64 (app-66.photo.163.org) 12/14/16 _x86_64_ (16 CPU)

11:30:28 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
11:30:28 all 0.63 0.00 0.32 0.06 0.00 0.11 0.00 0.00 98.88

6、負載與CPU利用率的關係

負載和CPU利用率都是衡量CPU性能的指標,那麼CPU利用率高的話負載一定高嗎?要回答這個問題首先要CPU資源在什麼情況下會被消耗,CPU利用率其實是指為了處理進程搶佔CPU時間片的比例,也就是只有處於運行狀態的進程才會獲得時間片,從而造成CPU利用率的上升,而所需CPU時間片的多少取決於進程中需要CPU運算邏輯的複雜程度。而負載是指運行隊列中等待和運行的進程數的總和,在負載很高時,可能是出於等待運行的進程數較多,這些進行並不會佔用過多的時間片,隊列中進程消耗的CPU資源也有可能只是集中在某幾個對CPU運算依賴較高的幾個進程上。所以CPU利用率和負載之間並沒有硬性的比例關聯關係,衡量CPU性能時要同時關注兩個性能指標,綜合考慮。

7、遇到CPU利用率高該如何排查

遇到CPU使用率高時,首先確認CPU是消耗在哪一塊,如果是內核態佔用CPU較高:

  1. %iowait 高,這時要重點關注磁碟IO的相關操作,是否存在不合理的寫日誌操作,資料庫操作等;
  2. %soft或%cs 高,觀察CPU負載是否較高、網卡流量是否較大,可不可以精簡數據、代碼在是否在多線程操作上存在不合適的中斷操作等;
  3. %steal 高,這種情況一般發生在虛擬機上,這時要查看宿主機是否資源超限;

如果是用戶態較高,且沒有達到預期的性能,說明應用程序需要優化(java應用):

  1. 可以使用性能組腳本 show-busy-java-threads.sh(top和jstack命令的結合)抓去CPU利用率高的線程堆棧,查看相關操作;
  2. 也可使用 jprofile 進行CPU熱點的監控,操作步驟見wiki:doc.hz.netease.com/page

8、性能指標總結

從網上看到一個按照經驗給出的指標,可以參考:

  1. 對於每一個CPU來說運行隊列不要超過2,例如,如果是雙核CPU就不要超過4;
  2. 如果CPU在滿負荷運行,應該符合下列分布:
  • User Time:65%~70%,如果高於此數值可以考慮對應用程序進行優化;
  • System Time:30%~35%,高於此數值時,觀察是否有過多的中斷或上下文切換;
  • Idle:0%~5%

3 對於上下文切換要結合CPU使用率來看,如果CPU使用滿足上述分布,大量的上下文切換也是可以接受的。

原文:Linux CPU性能指標淺析

免費領取驗證碼、內容安全、簡訊發送、直播點播體驗包及雲伺服器等套餐

更多網易技術、產品、運營經驗分享請點擊。


推薦閱讀:
相关文章