Linux效能優化實戰(一)

MXC肖某某發表於2022-02-07

一、優化方向

1,效能指標

  從應用負載的視角出發,考慮“吞吐”和“延時”

  從系統資源的視角出發,考慮資源使用率、飽和度等

  Linux效能優化實戰(一)

2,效能優化步驟

  • 選擇指標評估應用程式和系統的效能;
  • 為應用程式和系統設定效能目標;
  • 進行效能基準測試;
  • 效能分析定位瓶頸;
  • 優化系統和應用程式;
  • 效能監控和告警。

3,Linux效能工具圖譜

二、平均負載

1,stress

安裝命令:apt install stress
  stress 是一個linux系統壓力測試工具,這裡我們用作異常程式模擬平均負載升高場景
#模擬一個CPU使用率 100%  stress -c N 會讓stress生成N個工作程式進行開方運算,以此對CPU產生負載。
stress --cpu 1 --timeout 600
#模擬I/O密集程式 stress -i N  會產生N個程式,每個程式反覆呼叫sync()將記憶體上的內容寫到硬碟上, --timeout 600 表示600秒後退出 stress -i 1 --timeout 600

2,sysstat

安裝命令:apt install sysstat
sysstat 是一個常用的linux效能工具,用來監控和分析系統的效能。
  • mpstat 是一個常用的多核cpu效能分析工具,用來實時檢視每個CPU的效能指標,以及所有CPU的平均指標 
  • mpstat -P ALL 5   
    其中-P ALL  表示監控所有CPU
    數字5,表示每間隔5秒輸出一組資料
  • pidstat 是一個常用的程式效能分析工具,用來實時檢視程式的CPU、記憶體、IO以及上下文切換等效能指標
  • pidstat -u 5 1
    每間隔5秒輸出一組資料

3,場景模擬

a>CPU密集

  stress

#模擬一個CPU使用率 100%  stress -c N 會讓stress生成N個工作程式進行開方運算,以此對CPU產生負載。--timeout 600 表示600秒後退出 
stress --cpu 1 --timeout 600

  監控uptime,負載在升高

  mpstat,發現一個CPU的使用率高達100%,但是iowait為0,說明平均負載的升高由於CPU的使用率為100%

   pidstat,發現是stress程式導致CPU使用率升高

 

b>I/O密集

  stress

#模擬I/O密集程式  stress -i N  會產生N個程式,每個程式反覆呼叫sync()將記憶體上的內容寫到硬碟上
stress -i 1 --timeout 600

  監控uptime,負載在升高

  mpstat,發現一個系統CPU使用率升至23.87%,iowait高達67.53% 。說明平均負載的升高由於iowait的升高

  

  

  pidstat,發現是由於stress程式導致

c>大量程式的場景

  stress

stress -c 8 --timeout 600

  uptime

  pidstat,發現8個程式在爭搶2個CPU,每個程式等待CPU的時間高達75%,導致CPU過載

三、CPU的上下文切換

1,基本概念

  CPU暫存器:CPU內建的容量小、但速度極快的記憶體

  程式計數器:用於儲存CPU正在執行的指令位置、或者即將執行的下一條指令位置

  CPU上下文:CPU暫存器和程式計數器所必須的依賴環境

  CPU上下文切換:先把前一個任務的CPU上下文(也就是CPU暫存器和程式計數器)儲存起來,然後載入新任務的上下文到這些暫存器和程式計數器,最後再跳轉到程式計數器所指的新位置,執行新任務。

2,分類

a>程式上下文切換

  Linux按照特權等級,把程式的執行空間分為核心空間和使用者空間,分別對應CPU特權等級的 Ring 0 和Ring 3

  • 核心空間(Ring 0)具有最高許可權,可以直接訪問所有資源
  • 使用者空間(Ring 3)只能訪問受限資源,不能直接訪問記憶體等硬體裝置,必須通過系統呼叫陷入核心中,才能訪問這些特權資源

  

  換個角度,也就是程式既可以在使用者空間執行,又可以在核心空間執行。程式在使用者空間執行時,被稱為程式的使用者態,而陷入核心空間的時候,被稱為程式的核心態。

  在程式切換時才需要切換上下文,也就是程式排程時。Linux為每個CPU都維護了一個就緒佇列,將活躍程式按照優先順序和等待CPU的時間排序,然後選擇最需要CPU的程式,也就是優先順序最高和等待CPU時間最長的程式執行。涉及到的場景包括:

  • 為了保證所有程式可以得到公平排程,CPU時間被劃分為一段段的時間片,這些時間片再被輪流分配給各個程式。這樣,當某個程式的時間片耗盡了,就會被系統掛起,切換到其他正在等待CPU的程式執行
  • 程式在系統資源不足(比如記憶體不足)時,要等到資源滿足後才可以執行,這個時候程式也會被掛起,並有系統排程其他程式執行
  • 當程式通過睡眠函式sleep這樣的方法將自己主動掛起時,自然也會重新排程
  • 當有優先順序更高的程式執行時,為了保證高優先順序程式的執行,當前程式會被掛起,由高優先順序程式來執行
  • 當發生硬體中斷時,CPU上的程式會被中斷掛起,轉而執行核心中的中斷服務程式

b>執行緒上下文切換

  執行緒是排程的基本單位,而程式則是資源擁有的基本單位

  • 當程式只有一個執行緒時,可以認為程式就等於執行緒
  • 當程式擁有多個執行緒時,這些執行緒會共享相同的虛擬記憶體和全域性變數等資源。這些資源在上下文切換時不需要修改
  • 執行緒也有自己的私有資料,比如棧和暫存器,這些在上下文切換時也需要儲存

  執行緒上下文切換:1,前後兩個執行緒屬於不同程式,由於資源不同就是程式上下文切換;2,前後兩個執行緒屬於同一個程式,此時虛擬記憶體共享,切換時只需要切換執行緒的私有資料、暫存器等不共享的資料。

c>中斷上下文切換

  • 為了快速響應硬體的事件,中斷處理會打斷程式的正常排程和執行,轉而呼叫中斷處理程式,響應裝置事件。而在打斷其他程式時,就需要將程式當前的狀態儲存起來,這樣在中斷結束後,程式仍然可以從原來的狀態恢復執行
  • 與程式上下文切換不同,中斷上下文切換並不涉及程式的使用者態。所以,即便中斷過程打斷了一個正處在使用者態的程式,也不需要儲存和恢復這個程式的虛擬記憶體、全域性變數等使用者態資源。中斷上下文,其實只包括核心態中斷服務程式執行所必需的狀態,包括CPU暫存器、核心堆疊、硬體中斷引數等

3,CPU上下文切換實戰

a>vmstat

  

  • cs(context switch)是每秒上下文切換的次數
  • in(interrupt)是每秒中斷的次數
  • r(Running or Runnable)是就緒佇列的長度,也就是正在執行和等待的CPU的程式數‘
  • b(Blocked)是處於不可中斷睡眠狀態的程式數

b>pidstat

  vmstat只給出了系統總體的上下文切換情況,要想檢視每個程式的詳細情況,就需要使用我們pidstat。加上-w選項,則可以檢視每個程式上下文切換的情況

  

  • cswch(voluntary context switches),每秒自願上下文切換次數。指程式無法獲取所需要資源,導致的上下文切換。比如:I/O、記憶體等系統資源不足時,就會發生自願上下文切換。
  • nvcswch(non voluntary context switches),每秒非自願上下文切換。指程式由於時間片已到等原因,被系統強制排程,程式發生的上下文切換。比如:大量程式都在爭搶CPU時,就容易發生非自願上下文切換。

c>案例實操

  檢視系統的上下文切換次數 

 

   採用sysbench進行壓測

  

  再次檢視vmstat

  

   發現cs列的上下文切換數量從之前的35驟然上升到了139萬多。同時,r列:就緒佇列的長度為8,遠超CPU的個數2,所以判定有大量的CPU競爭;us(user)和sy(system)列:這兩列的CPU使用率加起來上升到了100%,其中系統CPU使用率,也就是sy列高達84%,說明CPU主要是被核心佔用了;in列:中斷次數也上升到1萬左右,說明中斷處理也是個潛在的問題。綜合這幾個指標,系統的就緒佇列過長,也就是正在執行和等待CPU的程式數過多,導致大量的上下文切換,而上下文切換又導致系統的CPU的佔用率升高。

  採用pidstat分析

  

  

  • CPU使用率升高果然是sysbench導致的,已達100%
  • 非自願上下文切換最高的為pidstat,自願上下文切換頻率最高的執行緒為kworker和sshd
  • 問題:pidstat輸出的上線文切換明顯小於vmstat輸出的上下文切換。採用man pidstat 發現,pidstat預設顯示程式的指標資料,加上-t引數後,才會輸出執行緒指標

  

  結合兩次的pidstat可以看出,sysbench(主執行緒)的上下文切換次數看起來並不太多,但它的子執行緒的上下文切換次數卻很多。

  採用watch觀察interrupts中斷

  

  觀察發現,變化速度最快的是重排程中斷(RES),表示喚醒空閒狀態的CPU來排程新的任務執行。這是多處理器系統(SMP)中,排程器用來分散任務到不同CPU的機制,通常也被稱為處理器間中斷(Inter-Processor Interrupts, IPI)。

d>總結

  如果系統的上下文切換次數比較穩定,那麼從數百到一萬內,都應該算是正常的。當上下文切換次數超過一萬次,或者切換次數出現數量級的增長時,都很可能已經出現了效能問題:

  • 自願上下文切換變多,說明程式都在等待資源,有可能發生了I/O等其他問題
  • 非自願上下文切換變多,說明程式都在被強制排程,也就是都在爭搶CPU,說明CPU的確成了瓶頸
  • 中斷次數變多了,說明CPU被中斷處理程式佔用,需要檢視/proc/interrupts檔案來分析具體的中斷型別

 

相關文章