1. 程式人生 > 實用技巧 >17丨CentOS:作業系統級監控及常用計數器解析

17丨CentOS:作業系統級監控及常用計數器解析

首先,我們前面在效能分析方法中提到,效能分析要有起點,通常情況下,這個起點就是響應時間、TPS等壓力工具給出來的資訊。

我們判斷了有瓶頸之後,通過拆分響應時間就可以知道在哪個環節上出了問題,再去詳細分析這個作業系統。這就需要用到我們的分析決策樹了。

你還記得我們在第6篇文章中提到的分析決策大樹嗎?今天我們單獨把作業系統的這一環節給提出來,並加上前面說的細化過程,就可以得到下面的這個分析決策樹。

在分段分層確定了這個系統所執行的應用有問題之後,還要記起另一件事情,就是前面提到的“全域性—定向”的監控思路。

既然說到了全域性,我們得先知道作業系統中,都有哪些大的模組。這裡就到了幾乎所有效能測試人員看到就想吐的模組了,CPU、I/O、Memory、Network…

沒辦法,誰讓作業系統就這麼點東西呢。我先畫一個思維導圖給你看一下。

我很努力地把一些常見指標的相應關係都畫到了圖中,你是不是已經看暈了?看暈就對了,彆著急。

我們先要知道的是,面對這些大的模組,到底要用什麼的監控手段來實現對它們的監控呢?要知道,在一篇文章中不可能詳盡地描述作業系統,我會盡量把我工作中經常使用到的一些和效能分析相關的、使用頻度高的知識點整理給你。

監控命令

我們經常用到的Linux監控命令大概有這些:topatopvmstatiostatiotopdstatsar等……請你注意我這裡列的監控命令是指可以監控到相應模組的計數器,而不是說只能監控這個模組,因為大部分命令都是綜合的工具集。

像這樣的監控工具還能列上一堆,但這並不是關鍵,關鍵的是我們在什麼時候能想起來用這些工具,以及知道這些工具的侷限性。

比如說top,它能看CPU、記憶體、Swap、執行緒列表等資訊,也可以把I/O算進去,因為它有CPU的wa計數器,但是它看不了Disk和Network,這就是明顯的侷限性。之後出現的atop對很多內容做了整理,有了Disk和Net資訊,但是呢,在一些Linux發行版中又不是預設安裝的。vmstat呢?它能看CPU、記憶體、佇列、Disk、System、Swap等資訊,但是它又看不了執行緒列表和網路資訊。

像這樣的侷限,我還能說上兩千字。

當工具讓你眼花繚亂的時候,不要忘記最初的目標,我們要監控的是這幾大模組:CPU、I/O、Memory、Network、System、Swap。

然後,我們再來對應前面提到的“全域性—定向”監控的思路。如果你現在僅用命令來監控這個系統,你要執行哪幾個呢?

對應文章前面的思維導圖,我們做一個細緻的表格。

你會發現,vmstat可以看Swap,但它能看的是siso,看不到其他的計數器,但是top可以看到這些計數器……像這樣的細節還有很多。

因為計數器非常多,又不是每個都常用。但是萬一某個時候就需要用了呢?這個時候如果你不知道的話,就無法繼續分析下去。

這裡我主要想告訴你什麼呢?就是用命令的時候,你要知道這個命令能幹什麼,不能幹什麼。你可能會說,有這些麼多的計數器,還有這麼多的命令,光學個OS我得學到啥時候去?

我要告訴你的是監控的思考邏輯。你要知道的是,正是因為你要監控CPU的某個計數器才執行了這個命令,而不是因為自己知道這個命令才去執行。這個關係我們一定要搞清楚。

那麼邏輯就是這樣的:

比如說,我想看下OS各模組的效能表現,所以執行top這個命令看了一些計數器,同時我又知道,網路的資訊在top中是看不到的,所以我要把OS大模組看完,還要用netstat看網路,以此類推。

如果你還是覺得這樣不能直接刺激到你的神經,懵懂不知道看哪些命令。那麼在這裡,我用上面的工具給你做一個表格。

命令模組對照表:

我雖然給出了這張表,但要想融會貫通,還需要你親手畫幾遍,每個命令都練習很多遍。好,這個時候,我們就已經把全域性監控的第一層的計數器基本看完了。

如果你站起來說:“高老師!你忽悠我,我這還有個想看的,你這裡還沒有!”

那你就在上面的表格中加上你想看的計數器和相關的命令就可以了,你的這個表格就會越來越豐富,豐富的過程中,也就慢慢釐清了自己的思路。

有了這些命令墊底之後,下面我們來看常用的監控平臺。

監控平臺Grafana+Prometheus+node_exporter

這是現在用得比較多的監控平臺了。在微服務時代,再加上Kubernetes+Docker的盛行,這個監控套裝幾乎是幹IT的都知道。

我們來看一下常用的Dashboard。為了理解上的通用性,我這裡都用預設的資訊,不用自己定製的。

Grafana.com官方ID:8919的模板內容如下:

還記得我們要看系統的模組是哪幾個嗎?

  • CPU
  • Memory
  • I/O
  • Network
  • System
  • Swap

你可以自己對一下,是不是大模組都沒有漏掉?確實沒有。但是!上面的計數器你得理解。

我們先來看一下CPU。

上圖中有了System、User、I/O Wait、Total,還記得我們上面說top裡有8個CPU計數器吧,這裡就4個怎麼辦?

Total這個值的計算方式是這樣的:

    1 - avg(irate(node_cpu_seconds_total{instance=~"$node",mode="idle"}[30m])) by (instance)

也就是說,它包括除了空閒CPU的其他所有CPU使用率,這其實就有ni、hi、si、st、guest、gnice的值。當我們在這個圖中看到System、User、I/O Wait都不高時,如果Total很高,那就是ni、hi、si、st、guest、gnice計數器中的某個值大了。這時你要想找問題,就得自己執行命令查看了。

看完CPU之後,再看一下Network。

上圖中有網路流量圖。可以看到只有“上傳下載”,這個值似乎容易理解,但是不夠細緻。node_exportor還提供了一個“網路連線資訊”圖。可以看到Sockets_used、CurrEstab、TCP_alloc、TCP_tw、UDP_inuse這些值,它們所代表的含義如下:

  • Sockets_used:已使用的所有協議套接字總量
  • CurrEstab:當前狀態為 ESTABLISHED 或 CLOSE-WAIT 的 TCP 連線數
  • TCP_alloc:已分配(已建立、已申請到sk_buff)的TCP套接字數量
  • TCP_tw:等待關閉的TCP連線數
  • UDP_inuse:正在使用的 UDP 套接字數量

這些值也可以通過檢視“cat /proc/net/sockstat”知道。這是監控工具套裝給我們提供的便利,

然後我們再來看下Memory。

上圖中有總記憶體、可用記憶體、已用記憶體這三個值。如果從應用的角度來看,我們現在對記憶體的分析,就要和語言相關了。像Java語言,一般會去分析JVM。我們對作業系統的實體記憶體的使用並不關注,在大部分場景下實體記憶體並沒有成為我們的瓶頸點,但這並不是說在記憶體上就沒有調優的空間了。

關於記憶體這一塊,我不想展開太多。因為展開之後內容太多了,如果你有興趣的話,可以找記憶體管理的資料來看看。

其他幾個模組我就不再一一列了,I/O、System、Swap也都是有監控資料的。

從全域性監控的角度上看,這些計數器也基本夠看。但是對於做效能分析、定位瓶頸來說,這些值顯然是不夠的。

還記得我在前面提到的“先全域性監控再定向監控”找證據鏈的理念吧。像node_exporter這樣的監控套裝給我們提供的就是全域性監控的資料,就是大面上覆蓋了,細節上仍然不夠。

那怎麼辦呢?下面我就來一一拆解一下。

CPU

關於CPU的計數器,已經有很多的資訊了。這裡我再囉嗦一下。CPU常見的計數器是top中的8個值,也就是下面這些:

%Cpu(s):  0.7 us,  0.5 sy,  0.0 ni, 98.7 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st

含義我就不寫了,你搜一下就會知道。

在mpstat(Multi-Processor Statistics)中看到的是10個計數器:

[root@7dgroup3 ~]# mpstat -P ALL 3
Linux 3.10.0-957.21.3.el7.x86_64 (7dgroup3) 	12/27/2019 	_x86_64_	(2 CPU)


03:46:25 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
03:46:28 PM  all    0.17    0.00    0.17    0.00    0.00    0.00    0.00    0.00    0.00   99.66
03:46:28 PM    0    0.33    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.67
03:46:28 PM    1    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00

這裡多出來%guest%gnice兩個值。他們的含義在Linux man page中有詳細的說明。

%guest :Show the percentage of time spent by the CPU or CPUs to run a virtual processor.

%gnice:Show the percentage of time spent by the CPU or CPUs to run a niced guest.

你可以看到計數器的名字稍有不同,像top中的wampstat中是%iowaitsi是mpstat中的%soft

在Linux中,這就是我們經常檢視的CPU計數器了。在我的效能生涯中,常見的問題大部分都是體現在這麼幾個計數器上(排名有先後):

  1. us
  2. wa
  3. sy
  4. si

首先,為了確定看到CPU高之後,接著往下分析的方向是絕對沒有錯的,建議你用Perf top -g先看一下CPU熱點。perf預設用的是cpu-clock事件。這一步只是為了確定方向對不對。

那麼如何從這幾個計數器找到後續的證據鏈呢?下面就是我們定向監控分析的過程了。我要狂敲黑板了!!!

us CPU是使用者態程序消耗的CPU百分比。大家都知道怎麼往下落。這個鏈就是下面這樣的:

當然不是隻有這幾個命令可以用,你可以找到大把的工具用,我只是列出來常用的。你要是想炫技,可以自己寫些指令碼來做。這個過程幾乎被寫爛了,所以,我就不多餘舉例子了。

wa cpu是I/O讀寫等待消耗的CPU百分比。這個證據鏈怎麼往下落呢?來看一下。

你看中間有一步跳躍,這就是wa CPU直接跳到執行緒了。為什麼沒有程序了呢?那是因為iotop有直接到執行緒的能力。如果你想先看程序也可以,記得執行iotop -P。

sy CPU是核心消耗的CPU百分比。這個問題就有點複雜了,因為它並沒有一個固定的套路。但是它的分析鏈路仍然和us CPU高的分析鏈路差不多,只是這個程序可能不是應用的,而是系統自己的。但是,是什麼導致核心程序佔用CPU高呢。這可能和應用有關,當然也可能和配置有關。那麼現在我們畫一個它的分析鏈路。

其實在實際的分析過程中,也是這樣的。如果我們看到一個系統的程序消耗了更多的資源,那就要去查一下這個程序是幹嗎的,看它的執行邏輯和配置檔案。不一定所有情況都是配置的問題,但絕大多數情況是這個原因,只能說,在系統級別,我們遇到的核心程序本身有效能問題的情況還是很少的。大部分時候都只是配置問題。

si CPU是軟中斷消耗的CPU百分比。什麼是軟中斷呢?在wikipedia.org中有這樣的描述:

In digital computers, an interrupt is an input signal to the processor indicating an event that needs immediate attention. An interrupt signal alerts the processor and serves as a request for the processor to interrupt the currently executing code, so that the event can be processed in a timely manner. If the request is accepted, the processor responds by suspending its current activities, saving its state, and executing a function called an interrupt handler (or an interrupt service routine, ISR) to deal with the event. This interruption is temporary, and, unless the interrupt indicates a fatal error, the processor resumes normal activities after the interrupt handler finishes.

簡單點來說,當出現異常或資源爭用時,它是用來管理秩序的。CPU正在吭哧吭哧著幹活呢,突然來了一個優先順序高的,needs immediate attention,這時就會發一箇中斷訊號給CPU。作為一個幹活的,CPU誰的話都得聽,這時候就把手頭的工作現場儲存一下,幹這個優先順序高的活。除非這個中斷是致命的,不然CPU會在幹完這個活之後再回去幹之前的活,這就是一次軟中斷。

這個值,越多就越有問題,關鍵是它有多少才是有問題呢?這一點你從來沒有看過有人給建議值對不對?因為它根本沒有可以參考的值,在不同的應用和硬體環境中,si CPU都會有很大差別。我見過軟中斷每秒幾萬多就有問題的,也見過軟中斷每秒20萬都沒有問題的。

下面我來照例畫個分析的圖看一下。

在這個判斷的鏈路中,就是要把si的中斷模組找出來,然後再分析這個模組的功能和配置。比如我們看網絡卡的中斷,這是常見的一種效能問題。我們要知道網路是頻寬不夠?還是配置得不對?還是防火牆?還是啥啥啥別的原因?

如果是其他的模組也是一樣的邏輯。

好,在知道了上面這幾個常見的CPU計數器的分析證據鏈邏輯之後,我就不再詳細畫其他的CPU的計數器了。

ni呢,在我職業生涯中就沒見過它高過;hi倒是見過,不過是因為硬體壞了;st呢,只有無良商家不斷超賣虛擬伺服器才會出現。如果你在一個企業內部搭建的虛擬化基礎平臺上也經常看見這種情況,那就是公司太窮了,硬體都不夠用。

總結

在作業系統的分析過程中,CPU絕對是一個重點分析的物件,它的一舉一動都牽動著效能分析的人,所以我們需要在CPU的高低上花很多的時間去分析判斷。

幸運的是,當CPU使用率高的時候,我們可以有很多的手段來找到對應的根本原因。這個過程不僅分析思路完整,而且工具繁多。它不像網路那麼繞,也不像記憶體那麼複雜,邏輯上還是很清楚的。