天天看點

61秒,摸透Linux的健康狀态!

61秒,摸透Linux的健康狀态!
原創:小姐姐味道(微信公衆号ID:xjjdog),歡迎分享,非公衆号轉載保留此聲明。

作業系統作為所有程式的載體,對應用的性能影響是非常重要的。然而計算機各個元件之間的速度,是非常不均衡的。拿CPU和硬碟的速度來說,比兔子和烏龜的速度差别還要大。

下面将簡單的介紹CPU、記憶體、I/O的一些基本知識,以及一些如何評估它們性能的指令。

1.CPU

首先介紹計算機中最重要的計算元件:中央處理器。一般我們可以通過top指令來觀測它的性能。

1.1 top指令

​top​

​​指令可用于觀測CPU的一些運作名額。如圖,進入​

​top​

​​指令之後,按​

​1​

​鍵即可看到每核CPU的詳細狀況。

61秒,摸透Linux的健康狀态!

CPU的使用有多個次元的名額,以下分别說明一下:

  • us 使用者态所占用的CPU百分比。
  • sy 核心态所占用的CPU百分比。如果這個值過高,需要配合vmstat指令,檢視是否是上下文切換是否頻繁。
  • ni 高優先級應用所占用的CPU百分比。
  • wa 等待I/O裝置所占用的CPU百分比。如果這個值非常高,輸入輸出裝置可能存在非常明顯的瓶頸。
  • hi 硬體中斷所占用的CPU百分比。
  • si 軟中斷所占用的CPU百分比。
  • st 這個一般發生在虛拟機上,指的是虛拟CPU等待實際CPU時間的百分比。如果這個值過大,則你的主控端壓力可能過大。如果你是雲主機,則你的服務商可能存在超賣。
  • id  空閑CPU百分比。

一般的,我們比較關注空閑CPU的百分比,它可以從整體上展現CPU的利用情況。

1.2 什麼是負載

我們還要評估CPU任務執行的排隊情況,這些值就是​

​負載​

​(load)。top指令,顯示的CPU負載,分别是最近1分鐘、5分鐘、15分鐘的數值。

61秒,摸透Linux的健康狀态!

如圖,以單核作業系統為例,将CPU資源抽象成一條單向行駛的馬路。則會發生三種情況:

  • 馬路上的車隻有​

    ​4​

    ​輛,車輛暢通無阻,load大約是0.5。
  • 馬路上的車有8輛,正好能首尾相接安全通過,此時load大約為1。
  • 馬路上的車有12輛,除了在馬路上的8輛車,還有4輛等在馬路外面,需要排隊。此時load大約為1.5。

那load為1代表的是啥?針對這個問題,誤解還是比較多的。

很多同學認為,load達到1,系統就到了瓶頸,這不完全正确。load的值和cpu核數息息相關。舉例如下:

  • 單核的負載達到1,總load的值約1。
  • 雙核的每核負載都達到1,總load約2。
  • 四核的每核負載都達到1,總load約為4。

是以,對于一個load到了10,卻是16核的機器,你的系統還遠沒有達到負載極限。通過uptime指令,同樣能夠看到負載情況。

1.3 vmstat

要看CPU的繁忙程度,還可以通過vmstat指令。下面是vmstat指令的一些輸出資訊。

61秒,摸透Linux的健康狀态!

我們比較關注的有下面幾列:

  • ​b​

    ​ 存在于等待隊列的核心線程數目,比如等待I/O等。數字過大則cpu太忙。
  • ​cs​

    ​ 代表上下文切換的數量。如果頻繁的進行上下文切換,就需要考慮是否是線程數開的過多。
  • ​si​

    ​​/​

    ​so​

    ​ 顯示了交換分區的一些使用情況,交換分區對性能的影響比較大,需要格外關注。
$ vmstat 1
procs ---------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
34  0    0 200889792  73708 591828    0    0     0     5    6   10 96  1  3  0  0
32  0    0 200889920  73708 591860    0    0     0   592 13284 4282 98  1  1  0  0
32  0    0 200890112  73708 591860    0    0     0     0 9501 2154 99  1  0  0  0
32  0    0 200889568  73712 591856    0    0     0    48 11900 2459 99  0  0  0  0
32  0    0 200890208  73712 591860    0    0     0     0 15898 4840 98  1  1  0  0      

2.記憶體

2.1 觀測指令

61秒,摸透Linux的健康狀态!

要想了解記憶體對性能的一些影響,就需要從作業系統層面來看一下記憶體的分布。

我們在平常寫完代碼後,比如寫了一個C++程式,如果去檢視它的彙編,可以看到其中的記憶體位址,并不是實際的實體記憶體位址。

那麼應用程式所使用的,就是邏輯記憶體,這個學過計算機組成結構的同學都有了解。

邏輯位址可以映射到實體記憶體和虛拟記憶體上。比如你的實體記憶體是8GB,配置設定了16GB的SWAP分區,那麼應用可用的總記憶體就是24GB。

從top指令可以看到幾列資料,注意方塊括起來的三個區域,解釋如下:

61秒,摸透Linux的健康狀态!
  • VIRT 這裡就是虛拟記憶體,一般比較大,不用做過多關注。
  • RES  我們平常關注的就是這一列的數值,它代表了程序實際占用的記憶體。平常在做監控時,也主要是監控這個數值。
  • SHR 指的是共享記憶體,比如可以複用的一些so檔案等。

2.2 CPU緩存

由于CPU核記憶體之間的速度差異是非常大的,解決方式就是加入高速緩存。其實,這些高速緩存,往往會有多層,如下圖。

61秒,摸透Linux的健康狀态!

Java有大部分知識點是圍繞多線程的,那是因為,如果一個線程的時間片跨越了多個CPU,那麼就會存在同步問題。

在Java中,最典型的和CPU緩存相關的知識點,就是并發程式設計中,針對​

​Cache line​

​的僞共享(false sharing)問題。

僞共享是指:在這些高速緩存中,是以​

​緩存行​

​為機關進行存儲的。哪怕你修改了緩存行中一個很小很小的資料,它都會整個的重新整理。是以,當多線程修改一些變量的值時,如果這些變量在同一個緩存行裡,就會造成頻繁重新整理,無意中影響彼此的性能。

通過以下指令即可看到目前作業系統的緩存行大小。

cat      

通過以下指令可以看到不同層次的緩存大小。

[root@localhost ~]# cat /sys/devices/system/cpu/cpu0/cache/index1/size
32K
[root@localhost ~]# cat /sys/devices/system/cpu/cpu0/cache/index2/size
256K
[root@localhost ~]# cat /sys/devices/system/cpu/cpu0/cache/index3/size
20480K      

在JDK8以上的版本,通過開啟參數​

​-XX:-RestrictContended​

​​,就可以使用注解​

​@sun.misc.Contended​

​進行補齊,來避免僞共享的問題。在并發優化中,我們再詳細講解。

2.3 HugePage

回頭看我們最長的那副圖,上面有一個叫做​

​TLB​

​的元件,它的速度雖然高,但容量也是有限的。這就意味着,如果實體記憶體很大,那麼映射表的條目将會非常多,會影響CPU的檢索效率。

預設記憶體是以​

​4K​

​的page來管理的。如圖,為了減少映射表的條目,可采取的辦法隻有增加頁的尺寸。像這種将Page Size加大的技術,就是Huge Page。

61秒,摸透Linux的健康狀态!

HugePage有一些副作用,比如競争加劇,Redis還有專門的研究(​​redis.io/topics/late…​​ ,但在一些大記憶體的機器上,開啟後會一定程度上增加性能。

2.4 預先加載

另外,一些程式的預設行為,也會對性能有所影響。比如JVM的​

​-XX:+AlwaysPreTouch​

​參數。預設情況下,JVM雖然配置了Xmx、Xms等參數,但它的記憶體在真正用到時,才會配置設定。

但如果加上這個參數,JVM就會在啟動的時候,把所有的記憶體預先配置設定。這樣,啟動時雖然慢了些,但運作時的性能會增加。

3.I/O

3.1 觀測指令

I/O裝置可能是計算機裡速度最差的元件了。它指的不僅僅是硬碟,還包括外圍的所有裝置。

硬碟有多慢呢?我們不去探究不同裝置的實作細節,直接看它的寫入速度(資料未經過嚴格測試,僅作參考)。

61秒,摸透Linux的健康狀态!

可以看到普通磁盤的随機寫和順序寫相差是非常大的。而​

​随機寫​

​完全和cpu記憶體不在一個數量級。

緩沖區依然是解決速度差異的唯一工具,在極端情況比如斷電等,就産生了太多的不确定性。這些緩沖區,都容易丢。

最能展現I/O繁忙程度的,就是top指令和​

​vmstat​

​​指令中的​

​wa%​

​。如果你的應用,寫了大量的日志,I/O wait就可能非常的高。

61秒,摸透Linux的健康狀态!

對于硬碟來說,可以使用iostat指令來檢視具體的硬體使用情況。隻要%util超過了80%,你的系統基本上就跑不動了。

61秒,摸透Linux的健康狀态!

詳細介紹如下:

  • %util 最重要的判斷參數。一般地,如果該參數是100%表示裝置已經接近滿負荷運作了
  • Device 表示發生在哪塊硬碟。如果你有多快,則會顯示多行
  • avgqu-sz  這個值是請求隊列的飽和度,也就是平均請求隊列的長度。毫無疑問,隊列長度越短越好。
  • await 響應時間應該低于5ms,如果大于10ms就比較大了。這個時間包括了隊列時間和服務時間
  • svctm   表示平均每次裝置​

    ​I/O​

    ​操作的服務時間。如果​

    ​svctm​

    ​的值與​

    ​await​

    ​很接近,表示幾乎沒有​

    ​I/O​

    ​等待,磁盤性能很好,如果​

    ​await​

    ​的值遠高于​

    ​svctm​

    ​的值,則表示​

    ​I/O​

    ​隊列等待太長,系統上運作的應用程式将變慢。

3.2 零拷貝

kafka比較快的一個原因就是使用了zero copy。所謂的Zero copy,就是在操作資料時, 不需要将資料buffer從一個記憶體區域拷貝到另一個記憶體區域。因為少了一次記憶體的拷貝, CPU的效率就得到提升。

我們來看一下它們之間的差別:

61秒,摸透Linux的健康狀态!

要想将一個檔案的内容通過socket發送出去,傳統的方式需要經過以下步驟:

  • 将檔案内容拷貝到核心空間。
  • 将核心空間的内容拷貝到使用者空間記憶體,比如Java應用。
  • 使用者空間将内容寫入到核心空間的緩存中。
  • socket讀取核心緩存中的内容,發送出去。
61秒,摸透Linux的健康狀态!

零拷貝又多種模式,我們拿sendfile來說明。如上圖,在核心的支援下,零拷貝少了一個步驟,那就是核心緩存向使用者空間的拷貝。即節省了記憶體,也節省了CPU的排程時間,效率很高。

4.網絡

除了iotop、iostat這些指令外,sar指令可以友善的看到網絡運作狀況,下面是一個簡單的示例,用于描述入網流量和出網流量。

$ sar -n DEV 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015     _x86_64_    (32 CPU)

12:16:48 AM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
12:16:49 AM      eth0  18763.00   5032.00  20686.42    478.30      0.00      0.00      0.00      0.00
12:16:49 AM        lo     14.00     14.00      1.36      1.36      0.00      0.00      0.00      0.00
12:16:49 AM   docker0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

12:16:49 AM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
12:16:50 AM      eth0  19763.00   5101.00  21999.10    482.56      0.00      0.00      0.00      0.00
12:16:50 AM        lo     20.00     20.00      3.25      3.25      0.00      0.00      0.00      0.00
12:16:50 AM   docker0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
^C      

當然,我們可以選擇性的隻看TCP的一些狀态。

$ sar -n TCP,ETCP 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015    _x86_64_    (32 CPU)

12:17:19 AM  active/s passive/s    iseg/s    oseg/s
12:17:20 AM      1.00      0.00  10233.00  18846.00

12:17:19 AM  atmptf/s  estres/s retrans/s isegerr/s   orsts/s
12:17:20 AM      0.00      0.00      0.00      0.00      0.00

12:17:20 AM  active/s passive/s    iseg/s    oseg/s
12:17:21 AM      1.00      0.00   8359.00   6039.00

12:17:20 AM  atmptf/s  estres/s retrans/s isegerr/s   orsts/s
12:17:21 AM      0.00      0.00      0.00      0.00      0.00
^C      

5.End

不要寄希望于這些名額,能夠立刻幫助我們定位性能問題。這些工具,隻能夠幫我們大體​

​猜測​

​發生問題的地方,它對性能問題的定位,隻是起到輔助作用。想要分析這些bottleneck,需要收集更多的資訊。

繼續閱讀