Linux性能優(yōu)化實戰(zhàn)(一)

CPU性能篇


第一篇 如何理解平均負(fù)載

系統(tǒng)變慢首先想到的兩個命令top和uptime

uptime
02:34:03 up 2 days, 20:14,  1 user,  load average: 0.63, 0.83, 0.88
//當(dāng)前時間、系統(tǒng)運行時間、當(dāng)前系統(tǒng)登錄用戶數(shù)、過去1分鐘、5分鐘、15分鐘平均負(fù)載

平均負(fù)載:簡單來說就是單位時間內(nèi)系統(tǒng)處于可運行狀態(tài)不可中斷狀態(tài)的平均進(jìn)程數(shù),也就是平均活躍進(jìn)程數(shù)。

可運行狀態(tài) 處于Runable狀態(tài)的進(jìn)程,進(jìn)程狀態(tài)標(biāo)志為R

不可中斷狀態(tài) 一般是等待I/O的進(jìn)程,進(jìn)程狀態(tài)標(biāo)志位D

  • 如果平均負(fù)載為2意味著什么呢?
  • 在一個2核cpu上意味著所有cpu剛好都被占用
  • 在一個4核cpu上意味著cpu有50%的空閑
  • 在一個1核cpu上意味著有一半進(jìn)程競爭不到cpu
  • 平均負(fù)載多少為合理?

平均負(fù)載理想的情況為cpu的核數(shù),查詢cpu核數(shù)通過top命令或者從/proc/cpuinfo中讀取。

[root@fengniaoweb proc]# grep 'model name' /proc/cpuinfo | wc -l
4
  • 如果1、5、15分鐘都表現(xiàn)很平穩(wěn)說明系統(tǒng)很平穩(wěn)不存在過載
  • 如果1、5、15分鐘負(fù)載是逐漸升高的就要引起注意了,尤其是超過70%的時候

平均負(fù)載與CPU使用率

CPU使用率是指單位時間內(nèi)CPU繁忙情況的統(tǒng)計,而平均負(fù)載還包含了不可中斷的進(jìn)程(實際并未使用CPU)

  • CPU密集型進(jìn)程,平均負(fù)載一般與CPU使用率一致
  • I/O密集型進(jìn)程,平均負(fù)載升高CPU使用率不一定會升高
  • 大量等待調(diào)度的進(jìn)程也會讓平均負(fù)載和CPU使用率一起升高

工具篇

stress是一個linux系統(tǒng)壓力測試工具,可以用來模擬系統(tǒng)負(fù)載升高的場景

apt install stress  #安裝

sysstat包含了linux常用的性能監(jiān)控分析工具

  • mpstat是一個常用的多核cpu性能分析工具,用來實時查看cpu的性能,以及所有cpu的平均指標(biāo)
  • pidstat是一個常用的進(jìn)程性能分析工具,用來實時查看系統(tǒng)的CPU、內(nèi)存、I/O以及上下文切換等多個指標(biāo)

第二篇 CPU的上下文切換

背景

Linux是個多任務(wù)操作系統(tǒng),在執(zhí)行遠(yuǎn)大于CPU核數(shù)的任務(wù)時,任務(wù)并不是同時進(jìn)行的,而是操作系統(tǒng)根據(jù)調(diào)度算法將CPU輪流分配給多個任務(wù)執(zhí)行。

由此任務(wù)從哪里開始加載,又從哪里開始執(zhí)行?

這就需要引入CPU 寄存器和程序計數(shù)器(Program Counter,PC)

CPU寄存器:CUP內(nèi)容量小速度極快的內(nèi)存

程序計數(shù)器:用于存儲正在執(zhí)行的指令位置或者即將執(zhí)行的下一條指令位置

CPU寄存器和程序計數(shù)器是CPU運行任何任務(wù)前必須依賴的環(huán)境因此也叫CPU上下文

919-1.png

理解CUP上下文切換

先把前一個任務(wù)的CPU上下文(也就是CPU寄存器和程序計數(shù)器)保存起來,然后加載新任務(wù)的上下文并跳轉(zhuǎn)到新任務(wù)程序計數(shù)器所指位置開始執(zhí)行新任務(wù)的過程。

Linux權(quán)限等級

  • 內(nèi)核空間(Ring0)

? 擁有最高的權(quán)限等級,可以訪問系統(tǒng)內(nèi)所有資源

  • 用戶空間(Ring3)

? 只能訪問受限資源,不能直接訪問硬件設(shè)備,需要通過系統(tǒng)調(diào)用才能間訪問特權(quán)設(shè)備

919-2.png

用戶態(tài)與內(nèi)核態(tài)

進(jìn)程既可能在用戶空間運行,此時稱作用戶態(tài),又可能在在內(nèi)核空間運行此時稱作內(nèi)核態(tài),進(jìn)程一旦發(fā)生系統(tǒng)調(diào)用就需要從用戶態(tài)切換到內(nèi)核態(tài),調(diào)用完成后又要從內(nèi)核態(tài)切換回用戶態(tài)。所以一次系統(tǒng)調(diào)用會至少發(fā)生兩次CPU上下文切換

系統(tǒng)調(diào)用發(fā)生的上下文切換實際上還是在同一個進(jìn)程內(nèi),所以不會涉及到虛擬內(nèi)存等進(jìn)程資源的切換,因此也叫特權(quán)模式切換注意與進(jìn)程上下文切換區(qū)分

CPU上下文切換類型

  • 進(jìn)程的上下文切換

    919-3.png

  • ? 虛擬內(nèi)存、棧、全局變量等用戶態(tài)空間資源切換

  • ? 內(nèi)核堆棧、寄存器等內(nèi)核態(tài)空間資源切換

  • 線程的上下文切換

  • 同一個進(jìn)程內(nèi)的線程切換,不需要切換虛擬內(nèi)存、全局變量等共享資源

  • 跨進(jìn)程的線程切換,等同于進(jìn)程切換

  • 線程私有的棧和寄存器數(shù)據(jù)也在切換時也需要考慮保存

  • 中斷的上下文切換

  • 中斷不涉及到用戶態(tài),因此中斷的上下文切換只包含CPU寄存器、內(nèi)核堆棧、中斷參數(shù)等
    什么時候發(fā)生切換?

  • CPU的執(zhí)行周期以時間片為單位,執(zhí)行完成后如果還有其他任務(wù)等待執(zhí)行,則自動讓出時間片由操作系統(tǒng)從任務(wù)隊列中選擇最靠前的任務(wù)執(zhí)行

  • 進(jìn)程在等待系統(tǒng)資源(如內(nèi)存、IO等)時,任務(wù)被掛起,操作系統(tǒng)調(diào)度其他任務(wù)執(zhí)行

  • 進(jìn)程調(diào)用系統(tǒng)休眠函數(shù)比如sleep時,任務(wù)被掛起,操作系統(tǒng)調(diào)度其他任務(wù)執(zhí)行

  • 有更高優(yōu)先級任務(wù)到來,為保證高優(yōu)先級任務(wù)先執(zhí)行,當(dāng)前任務(wù)也會被掛起

  • 發(fā)生硬件中斷時,任務(wù)被掛起,轉(zhuǎn)而執(zhí)行內(nèi)核中的中斷服務(wù)程序

怎么查看CPU上下文切換?

VMSTAT是一款常用的系統(tǒng)性能分析工具,主要用來分析系統(tǒng)的內(nèi)存使用情況、也常用來分析CPU上下文切換和中斷的次數(shù)。下面為使用示例:

# 每隔 5 秒輸出 1 組數(shù)據(jù)
$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 7005360  91564 818900    0    0     0     0   25   33  0  0 100  0  0

重點關(guān)注以下4列

cs(context switch)是每秒上下文切換的次數(shù)。

in(interrupt)則是每秒中斷的次數(shù)。

r(Running or Runnable)是就緒隊列的長度,也就是正在運行和等待CPU的進(jìn)程數(shù)。

b(Blocked)則是處于不可中斷睡眠狀態(tài)的進(jìn)程數(shù)。

VMSTAT只能給出系統(tǒng)總體的上下文切換情況,想要查看每個進(jìn)程的詳細(xì)切換情況,就要使用pidstat命令了,加上-w選項。

# 每隔 5 秒輸出 1 組數(shù)據(jù)
$ pidstat -w 5
Linux 4.15.0 (ubuntu)  09/23/18  _x86_64_  (2 CPU)

08:18:26      UID       PID   cswch/s nvcswch/s  Command
08:18:31        0         1      0.20      0.00  systemd
08:18:31        0         8      5.40      0.00  rcu_sched
...

cswch ,表示每秒自愿上下文切換(voluntary context switches)的次數(shù)

nvcswch ,表示每秒非自愿上下文切換(non voluntary context switches)的次數(shù)

自愿上下文切換指進(jìn)程無法獲取到資源導(dǎo)致的切換,如等待IO、內(nèi)存等系統(tǒng)資源時

非自愿上下文切換指大量進(jìn)程爭搶CPU時,由于時間片已到等原因,被迫發(fā)生的切換

pidstat使用舉例

# 每隔 1 秒輸出 1 組數(shù)據(jù)(需要 Ctrl+C 才結(jié)束)
# -w 參數(shù)表示輸出進(jìn)程切換指標(biāo),而 -u 參數(shù)則表示輸出 CPU 使用指標(biāo)
$ pidstat -w -u 1
08:06:33      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
08:06:34        0     10488   30.00  100.00    0.00    0.00  100.00     0  sysbench
08:06:34        0     26326    0.00    1.00    0.00    0.00    1.00     0  kworker/u4:2

08:06:33      UID       PID   cswch/s nvcswch/s  Command
08:06:34        0         8     11.00      0.00  rcu_sched
08:06:34        0        16      1.00      0.00  ksoftirqd/1
08:06:34        0       471      1.00      0.00  hv_balloon
08:06:34        0      1230      1.00      0.00  iscsid
08:06:34        0      4089      1.00      0.00  kworker/1:5
08:06:34        0      4333      1.00      0.00  kworker/0:3
08:06:34        0     10499      1.00    224.00  pidstat
08:06:34        0     26326    236.00      0.00  kworker/u4:2
08:06:34     1000     26784    223.00      0.00  sshd
# 每隔 1 秒輸出一組數(shù)據(jù)(需要 Ctrl+C 才結(jié)束)
# -wt 參數(shù)表示輸出線程的上下文切換指標(biāo)
$ pidstat -wt 1
08:14:05      UID      TGID       TID   cswch/s nvcswch/s  Command
...
08:14:05        0     10551         -      6.00      0.00  sysbench
08:14:05        0         -     10551      6.00      0.00  |__sysbench
08:14:05        0         -     10552  18911.00 103740.00  |__sysbench
08:14:05        0         -     10553  18915.00 100955.00  |__sysbench
08:14:05        0         -     10554  18827.00 103954.00  |__sysbench
...

如何查看中斷次數(shù)?

因為中斷發(fā)生在內(nèi)核態(tài),所以不能通過pidstat查看,需要從/proc/interrupts 這個只讀文件中讀取。/proc 實際上是 Linux 的一個虛擬文件系統(tǒng),用于內(nèi)核空間與用戶空間之間的通信。/proc/interrupts就是這種通信機(jī)制的一部分,提供了一個只讀的中斷使用情況。

# -d 參數(shù)表示高亮顯示變化的區(qū)域
$ watch -d cat /proc/interrupts
           CPU0       CPU1
...
RES:    2450431    5279697   Rescheduling interrupts
...
  • 重調(diào)度中斷(RES)喚醒空閑狀態(tài)的CPU來調(diào)度新的任務(wù)運行
    如何通過切換次數(shù)發(fā)現(xiàn)問題?
  • 自愿上下文切換變多,說明都在等待資源,有可能發(fā)生了IO等其他問題
  • 非自愿上下文切換變多,說明都在爭搶CPU資源,CPU成為了瓶頸
  • 中斷次數(shù)變多了,說明CPU都被中斷處理程序占用,需要根據(jù)中斷類型具體分析原因

此為個人筆記,不涉及其他,僅做參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容