MySQL性能診斷實踐之系統觀測工具-愛可生

摘要:今天我帶來的分享是系統觀測工具,有所關聯但不涉及MySQL自身的這樣一個話題。


分享大綱:

1. MySQL 慢的診斷思路

2. 系統觀測工具介紹

3. bcc (eBPF腳本集) 使用舉例

4. eBPF 使用方法/限制


今天我帶來的分享是系統觀測工具,跟MySQL相關,但不是MySQL,選擇這個話題最主要的原因是今天4場演講,剛才是官方的專家來介紹MySQL的新特性,後面還有兩位專家,一位是介紹MySQL在真實業務中的大規模應用,還有一位是介紹源碼,留給我的空間並不是很多,所以選擇了一個跟MySQL有所關聯但不涉及MySQL自身的話題。


首先想請問一下大家,如果遇到MySQL慢的話大家的第一印象是什麼,MySQL數據庫如果性能不行的情況下,大家的處理手法是怎樣?


我諮詢了一些同行, 得到了以下反饋,第一反應是再試一次,第二個反應是優化一下SQL,第三個反應是我們調大buffer pool,然後開始換硬件了,換一下SSD,然後實在不行了我們找個搜索引擎問一下說“MySQL慢怎麼辦”。


如果大家用的是國內的搜索引擎的話,搜索引擎會推薦某某知道或者某某乎, 推薦一些MySQL調優經驗, 調大參數A, 調低參數, 諸如此類,類似的網站能告訴你MySQL慢怎麼辦。


MySQL性能診斷實踐之系統觀測工具-愛可生

我們來分析一下這些現象背後隱藏的意義:


MySQL性能診斷實踐之系統觀測工具-愛可生

  • 如果大家再試一次能夠成功的話, 意味著你可能碰到了不可復現的外界因素的影響,導致MySQL會慢。
  • 如果優化SQL能解決,就意味著SQL的執行復雜度遠遠大於它的需求複雜度。
  • 如果調大buffer pool能解決,就意味著MySQL碰到了自身的某些限制。
  • 如果換SSD能解決,那麼意味著服務器資源受到了一定的限制。
  • 如果需要搜索引擎,意味著調優這事已經變成了玄學。


所以今天我想向大家介紹的是四部分內容:


1.MySQL 慢的診斷思

2.系統觀測工具介紹

3.bcc (eBPF腳本集) 使用舉例

4.eBPF 使用方法/限制

MySQL性能診斷實踐之系統觀測工具-愛可生

第一部分,我們向大家介紹一下常規的MySQL診斷慢的思路,也是業界的常規思路。


第二部分,是今天介紹的主要命題 -- 系統觀測工具的相關內容,我們會大概瞭解一下什麼叫系統觀測工具。


第三部分,給大家介紹一個腳本集,這個腳本集是開源的,開箱即用並且可以幫助大家快速診斷MySQL的一些問題,我們直接使用10個例子 快速地介紹一下這個腳本集能為我們做到什麼。


最後,我們介紹一下eBPF的使用方法和腳本結構。任何一個好用的東西一定有它自己的限制,否則它就太完美了,所以我們也會介紹一下它的限制到底是怎樣的。


1.MySQL 慢的診斷思路


MySQL性能診斷實踐之系統觀測工具-愛可生

我們先來看第一個階段,MySQL慢的診斷思路,一般我們會從三個方向來做:


  • 第一個方向是MySQL內部的觀測
  • 第二個方向是外部資源的觀測
  • 第三個方向是外部需求的改造


1.1 MySQL 內部觀測


MySQL性能診斷實踐之系統觀測工具-愛可生

我們來看MySQL內部的觀測,常用的觀測手段是這樣的,從上往下看,第一部分是Processlist,看一下哪個SQL壓力不太正常,第二步是explain,解釋一下它的執行計劃,第三步我們要做Profilling,如果這個SQL能再執行一次的話, 就做一個Profilling,然後高級的DBA會直接動用performance_schema ,MySQL 5.7 以後直接動用sys_schema,sys_schema是一個視圖,裡面有便捷的各類信息,幫助大家來診斷性能。再高級一點,我們會動用innodb_metrics進行一個對引擎的診斷。


除了這些手段以外,大家還提出了一些亂七八糟的手段,我就不列在這了,這些是常規的一個MySQL的內部的狀態觀測的思路。除了這些以外,MySQL還陸陸續續提供了一些暴露自己狀態的方案,但是這些方案並沒有在實踐中形成套路,原因是學習成本比較高。


1.2 外部資源觀測

MySQL性能診斷實踐之系統觀測工具-愛可生

外部資源觀測這部分,我引用了一篇文章,這篇文章的二維碼我貼在上面了。這篇文章是國外的一個神寫的,標題是:60秒的快速巡檢,我們來看一下它在60秒之內對服務器到底做了一個什麼樣的巡檢。一共十條命令,這是前五條,我們一條一條來看。


MySQL性能診斷實踐之系統觀測工具-愛可生

1.uptime,uptime告訴我們這個機器活了多久,以及它的平均的負載是多少。

2.dmesg -T | tail,告訴我們系統日誌裡邊有沒有什麼報錯。

3.vmstat 1,告訴我們虛擬內存的狀態,頁的換進換出有沒有問題,swap有沒有使用。

4. mpstat -P ALL,告訴我們CPU壓力在各個核上是不是均勻的。

5.pidstat 1,告訴我們各個進程的對資源的佔用大概是什麼樣子。

MySQL性能診斷實踐之系統觀測工具-愛可生


我們來看一下後五條:

首先是iostat-xz 1,查看IO的問題,然後是free-m內存使用率,之後兩個sar,按設備網卡設備的維度,看一下網絡的消耗狀態,以及總體看TCP的使用率和錯誤率是多少。最後一條命令top,看一下大概的進程和線程的問題。


這個就是對於外部資源的診斷,這十條命令揭示了應該去診斷哪些外部資源。


1.3 外部需求改造

MySQL性能診斷實踐之系統觀測工具-愛可生


第三個診斷思路是外部的需求改造,我在這裡引用了一篇文檔,這篇文檔是MySQL的官方文檔中的一章,這一章叫Examples of Common Queries,文檔中介紹了常規的SQL怎麼寫, 給出了一些例子。文章的鏈接二維碼在slide上。


我們來看一下它其中提到的一個例子。


MySQL性能診斷實踐之系統觀測工具-愛可生


它做的事情是從一個表裡邊去選取,這張表有三列,article、dealer、price,選取每個作者的最貴的商品列在結果集中,這是它的最原始的SQL,非常符合業務的寫法,但是它是個關聯子查詢。


MySQL性能診斷實踐之系統觀測工具-愛可生


關聯子查詢成本是很貴的,所以上面的文檔會教你快速地把它轉成一個非關聯子查詢,大家可以看到中間的子查詢和外邊的查詢之間是沒有關聯性的。


MySQL性能診斷實踐之系統觀測工具-愛可生


第三步,會教大家直接把子查詢拿掉,然後轉成這樣一個SQL,這個就叫業務改造,前後三個SQL的成本都不一樣,把關聯子查詢拆掉的成本,拆掉以後SQL會跑得非常好,但這個SQL已經不能良好表義了,只有在診斷到SQL成本比較高的情況下才建議大家使用這種方式。


為什麼它能夠把一個關聯子查詢拆掉呢?


MySQL性能診斷實踐之系統觀測工具-愛可生


這背後的原理是關係代數,所有的SQL都可以被表達成等價的關係代數式,關係代數式之間有等價關係,這個等價關係通過變換可以把關聯子查詢拆掉。


上面的這篇文檔是一個大學的教材,它從頭教了關於代數和SQL之間的關係。然後一步步推導怎麼去簡化這句SQL。


第一,MySQL本身提供了很多命令來觀察MySQL自身的各類狀態,大家從上往下檢一般能檢到SQL的問題或者服務器的問題。


第二,從服務器的角度,我們從巡檢的腳本角度入手,服務器的資源就這幾種,觀測手法也就那麼幾種,我們把服務器的資源全部都觀察一圈就可以了。


第三,如果實在搞不定,需求方一定要按照數據庫容易接受的方式去寫SQL,這個成本會下降的非常快,這個是常規的MySQL慢的診斷思路。


2.系統觀測工具介紹

我們先從診斷思路的討論切換到系統的觀測工具,首先了解什麼叫系統觀測工具並且看一下它的舉例,然後再回到診斷思路上,看看新的工具的引入能為我們的思路到底帶來怎樣的改變。

MySQL性能診斷實踐之系統觀測工具-愛可生

先來看一下什麼叫系統觀測工具?援引這篇文檔,二微碼如上,這是一個外國人寫的文檔,我把這個文檔拆開,中間描述了三件事情:

MySQL性能診斷實踐之系統觀測工具-愛可生

第一,系統觀測工具的數據源來自於哪裡;

第二,數據採集過程,因為採集的是系統的運行狀況,所以到底如何採集這是一個難點;

第三,應該怎麼看數據,是用圖來看,還是用表來看,它就叫數據處理前端;

MySQL性能診斷實踐之系統觀測工具-愛可生

第一步,我們來看一下數據源,Linux給我們提供的數據源是這幾種,包括操作系統內核態提供的觀測點和用戶態提供的觀測點,MySQL很早之前就提供了用戶態的觀測點。

MySQL性能診斷實踐之系統觀測工具-愛可生

第二步,怎麼把數據抽出來,抽出來的時候,大家可以看到這些工具裡邊大家最熟悉的應該是perf和ftrace,然後sysdig也有人在用,其它的可能有所耳聞,這個是從操作系統裡邊抽取數據的方法。


MySQL性能診斷實踐之系統觀測工具-愛可生

第三步,數據處理前端,前端裡邊常用的也是perf和ftrace。如果大家對perf很熟悉的話會知道perf出來的數據是一個樹形的數據,並可以跟這棵樹進行交互,比如說: 查看某個函數運行了多久,哪一個函數的時間最長,這個是數據處理前端。


MySQL性能診斷實踐之系統觀測工具-愛可生

我們來對比一下常規的四類系統觀測工具今天我要介紹的是第三類,eBPF,我們過往常用的是第四個,前面這兩個是通用工具,我們來對比一下這四個到底有什麼不同,看看Linux到底為啥提供這麼多觀測工具。

MySQL性能診斷實踐之系統觀測工具-愛可生

第一,來看一下ftrace,ftrace是一個sysfs中的一個樁,通過這個樁內核提供了一種觀測的形式,這種觀測的形式就是把想觀測的函數的簽名打到這個樁裡,然後操作系統就會提供這個函數運行的狀況。ftrace的結構如左圖, 數據處理前端和採集端是ftrace, 數據源是下面這一堆。


MySQL性能診斷實踐之系統觀測工具-愛可生

第二,大家常用的perf,原理是操作系統提供了一個系統調用可以將數據寫到一個緩存中, 然後客戶端把這些數據端抽取出來然後呈現在顯示器上。這個是perf的運行原理。


MySQL性能診斷實踐之系統觀測工具-愛可生

第三,eBPF是我們今天要重點介紹的,eBPF的方案,跟剛才兩種方案不一樣,剛才兩種方案一種是操作系統提供的文件系統上的樁,一種是操作系統提供的系統調用,而eBPF是將一段代碼直接插到操作系統內核某一個位置上的機制。


MySQL性能診斷實踐之系統觀測工具-愛可生

第四,Systemtap的原理是將一段C的代碼編譯成了一個內核的模塊,然後將這個模塊嵌到內核裡邊去,它不是由內核提供的一個機制,而是由內核的模塊機制提供的一種功能。


這是四種觀測工具的不同。


為什麼要介紹這四種觀測工具的不同,是因為大家在選取觀測工具的時候就知道大概怎麼選。


這四種觀測工具裡邊對系統傷害最輕的是誰?


對系統傷害最輕的是系統調用,這是系統承諾出來的服務。然後是ftrace,這是系統在文件系統層面提供的一個口,告訴你可以通過這個口跟系統交互。


對系統侵入性最強的是誰?


對系統侵入性最強的應該是eBPF,因為它直接將一根代碼嵌入到系統裡邊去做,最不穩定的應該是System Tap,因為它是系統的一個模塊, 又提供了非常複雜的功能。

MySQL性能診斷實踐之系統觀測工具-愛可生

這張圖是eBPF的架構圖,eBPF先將一段程序編譯成二進制代碼,然後插到操作系統裡邊去,操作系統運行這段代碼的時候,將採集到的數據吐到操作系統本身的一個空間裡,然後再做統一返回,大概就是這樣的一個結構。


eBPF這個結構,最核心的部分在於把代碼插入到操作系統中運行,它需要做各種安全保護才能完成這一點,所以這也是這個機制複雜的地方。


3. bcc (eBPF腳本集) 使用舉例

我們引用了一個開源的eBPF腳本集bcc, 快速看一下eBPF能做什麼, 這些功能都是開箱即用。

MySQL性能診斷實踐之系統觀測工具-愛可生

第一個例子,MySQL的請求延遲分析,一個MySQL承擔了很多業務,上千個併發在那兒,哪一個SQL最慢,到底有哪些SQL在一秒以上,除了slow log以外,還可以用這種方法來看。

MySQL性能診斷實踐之系統觀測工具-愛可生

這個命令的結果分為三列,它的第一列是請求的延遲,指數級遞增,單位是微秒,中間一列是它的命中數,如果有一個請求命中了64-127微秒這個區間,命中數會加一,最後一列是它的分佈圖,它在同一個報告裡提供了數值的方式和圖的方式,大家很容易看到結果。


對於這臺服務器來說,我下了一個select的性能壓力,它大部分的請求集中於64到127微秒之間。這個數據庫的性能可能還不錯。

MySQL性能診斷實踐之系統觀測工具-愛可生

我們再來看另外一種壓力,我下了一個select+insert的混合壓力在一個數據庫裡,它的圖又變了,它呈現了一個非常好的雙峰圖,我將兩個峰值用另外一種顏色標明,這兩個峰值的意思是很有可能有混合壓力在一個數據庫裡,或者是上面的這部分壓力是命中了某些緩存,而下面的某些壓力是由於沒有命中緩存,導致這部分請求更慢一些, 形成另一個峰值,所以大家通過這種峰值分析可以看到數據庫大概的一個運行狀態。


如果能做得更好,大家可以抽檢自己的數據庫然後做環比圖,比如說今天和昨天同樣的時間,同樣的業務壓力下對數據庫的延遲進行分析,如果數據庫的延遲峰一直在往後延,就意味著數據庫的狀態在變得更糟糕一些。這是bcc第一個能做的事情,需要再次強調的是它開箱即用直接下載過來就可以使用。

MySQL性能診斷實踐之系統觀測工具-愛可生

第二個例子,MySQL的慢查詢

,MySQL本身提供很好的慢查詢,我幹嘛要用另外一個機制來獲取MySQL的慢查詢呢?

MySQL性能診斷實踐之系統觀測工具-愛可生

我們先看一下它的輸出,其實跟MySQL本身的慢查詢還要再簡單一些。那麼我們為什麼要用另外一種方式來獲取慢查詢呢?


MySQL性能診斷實踐之系統觀測工具-愛可生

因為它能做到這些事情,而MySQL的慢查詢可能很難做,與MySQL的慢日誌相比, 它可以低成本地完成:


1. 獲取少量慢查詢

2. 獲取某種模式的慢查詢

3. 獲取某個用戶的慢查詢


比如說獲取少量的慢查詢,為什麼是少量呢?因為我們不確定現在的線上延遲是多少,慢查詢只開一秒可能日誌瞬間就被堆上去,性能就會下來,但是如果慢查詢開個十秒左右,沒有請求在這個區間命中,所以要一點一點的去調這個值,比如說線上1%的最慢的查詢能夠命中,但是在這個腳本里面,可以取一定區間的最大的幾個查詢把它拎出來。


通過腳本還可以命中某種模式的慢查詢, 比如說我們只關心update的慢查詢, 那麼獲取select的結果就沒有太大的意義,或者是我一定要獲取某一些特定表的相關的查詢,我都可以通過腳本來做。


第三種情況我想獲取某個用戶的慢查詢,這個一般對於多租戶系統,因為多租戶系統我只想針對某一個用戶進行慢查詢分析的時候,這種腳本就比較好用,這是我想說的第二個例子。


MySQL性能診斷實踐之系統觀測工具-愛可生

之後的幾個例子都跟IO相關,所以我引用了另外一篇文檔,這篇文檔是Linux IO的堆棧圖,右邊是引用的二維碼,這張堆棧圖看起來很複雜,但這個其實是2012年畫的第一版的IO堆棧圖,現在IO堆棧圖比這個要複雜很多,大家可以在這個網址上去體驗一下。然後我們把其中的關鍵元素抽出來,我們看一下IO的堆棧大概是幾個層次?

MySQL性能診斷實踐之系統觀測工具-愛可生

從MySQL開始,MySQL是運行在用戶態中,它通過VFS層的接口,一個IO請求就下到內核態,然後從VFS轉到真正的文件系統,之後IO請求會下到塊設備層,在塊設備層裡邊會經歷IO的一個調度器,大家常見的MySQL的調優建議裡面, 對於調度器的設置要麼設成空要麼設成deadline, 就是在這個位置起作用,最後通過SCSI接口, 將數據請求下到物理設備。

MySQL性能診斷實踐之系統觀測工具-愛可生

第三個例子,VFS延遲分析,我們對每一層都可以通過腳本對它進行IO分析,比如說我可以對VFS做延遲分析。

MySQL性能診斷實踐之系統觀測工具-愛可生

對VFS做延遲分析,這是對數據庫進行了一個寫壓力,大家可以明顯看到一個雙峰圖,這是寫的兩個峰,是數據庫對於內核的寫壓力的反饋。


這個意味著什麼呢?這個可能意味著因為這部分的寫是命中了操作系統文件系統的緩存,而下面這部分寫是真正的寫穿到設備的,所以他們倆的延遲不一樣,這是一個典型的雙峰圖,大家需要把兩個峰拆開來去行這樣的分析。


換一個說法,如果寫壓力都集中在這裡,而沒有第二個峰的情況下,需不需要去更換物理設備?有可能不需要,因為所有的東西都命中了操作系統的緩存。

MySQL性能診斷實踐之系統觀測工具-愛可生

第四個例子,Ext4 文件IO延遲分析,我們之前看到的圖是以磁盤設備為維度的。

MySQL性能診斷實踐之系統觀測工具-愛可生

那麼我能不能按照文件維度去看到底是哪個文件的IO慢,這個腳本可以直接做到。 我下了一個最簡單的寫壓力到數據庫上。


紅色標明的地方比非紅色的地方的數值都要高,而它的共性在於都是數據文件,而非紅色的部分都是各類的日誌文件,這就是大家常說的日誌文件是順序寫的,數據文件是隨機寫的,順序寫比隨機寫快, 就在這個延遲上體現了,所以通過這種觀測方式大家可以觀測到各個文件的寫壓力的平均延遲大概在什麼水平上。

MySQL性能診斷實踐之系統觀測工具-愛可生

我用這個工具主要是用來抓住一些證據, 比如其他進程影響了數據庫的IO。在這個地方故意用了DD,不是打車的滴滴,是寫IO的DD,DD的IO壓力就會被工具抓出來, 這就是鐵的證據。這是我想介紹的第四個例子,它可以做基於文件的IO分析。


MySQL性能診斷實踐之系統觀測工具-愛可生

第五個例子,塊設備的延遲分析,為什麼要補充一個塊設備的延遲分析呢?因為從剛才的這些延遲分析上,延遲都是帶有操作系統緩存的影響的,而通過這個腳本可以看出真實下到設備上的延遲是多少。


MySQL性能診斷實踐之系統觀測工具-愛可生

這是一個下到設備上的壓力的情況, 大部分的延遲在32微秒到64微秒之間,我也不知道這個設備是好還是不好,做IO壓力的時候很難通過絕對值去判斷這個事是好還是不好,大家需要通過環比得出正確的結論。

MySQL性能診斷實踐之系統觀測工具-愛可生

這張雙峰圖, 是我的同事做出來的,他問我說這是個典型的雙峰圖,是不是IO出了問題設備出了問題,一組IO比另一組IO的延遲明顯要高。


那這個圖到底有沒有問題呢?這個圖沒有什麼太大的問題,因為它的count很小。它真實的select下在到設備上的讀只有五個請求,這五個請求裡邊明顯有三個比其它的兩個延遲要高一些,這個事兒不值得分析。大部分的請求全部都被InnoDB的buffer和操作系統的Cache全部都hold住了,所以這個事情是不值得分析的,大家通過這個圖也可以完成剛才“需不需要更換設備, 更換設備以後MySQL會不會變得更快”的問題,在如圖的情況下應該不會。

MySQL性能診斷實踐之系統觀測工具-愛可生

第六個例子,MySQL線程對文件的IO壓力彙總,我們看了剛才基於設備的、基於全局文件的IO壓力分析,我想知道MySQL到底哪一根線程對IO造成了壓力,是InnoDB負責刷數據的哪根線程,還是正在導數據的線程。

MySQL性能診斷實踐之系統觀測工具-愛可生

這個腳本可以幫大家做到這個事情,看看這個腳本的輸出結果是這樣的,它最左邊一列是TID,是線程號,最右邊一列是文件,中間部分是它寫的大小。在這樣的一個數據庫上,大家可以明顯看到這個數據庫出了什麼問題。


即使沒有my.cnf的內容也能知道這個數據庫出了什麼問題,它的問題可能在於開啟了general log。這個是基於線程的,所以大家只要找到這兩根線程, 就能知道這兩根線程是哪個業務下來的,這兩根線程的SQL可能異常多, 所以general log一直在刷日誌,刷成了現在這樣子。這個是基於線程,並且基於文件的對IO的分析。

MySQL性能診斷實踐之系統觀測工具-愛可生

第七個例子,短生命週期的臨時文件檢測,這個大家不一定常見,MySQL會在某些情況下動用臨時表, 如果SQL沒寫好就會創建臨時表,這些臨時表的生命週期很短,但是量很大,所以一定要寫文件而不能內存裡。


在這種情況下會對操作系統造成一些壓力,而這個壓力又不太好診斷,是因為臨時文件的生存週期短,所以這個腳本可以幫大家提供這樣的一個方案,這個方案的結果大概是這樣子。

MySQL性能診斷實踐之系統觀測工具-愛可生

我做了一個臨時表,這個臨時表活了5.3秒左右,於是它展現在了腳本的結果裡。如果大家掃描自己的線上MySQL發現這裡有大量的東西說明在大量的使用臨時表,如果IO壓力在此時比較大, 就可能受了臨時表的影響。

MySQL性能診斷實踐之系統觀測工具-愛可生

第八個例子,短連接分析,好一點的應用都會用連接池,但是我們很多的時候沒有那麼好的運氣,老碰到那麼好的應用,所以經常業務會扔過來大量的短連接。

MySQL性能診斷實踐之系統觀測工具-愛可生

這個例子中, sysbench上了一個大併發,但是隻活了300多毫秒,這些連接都只活了300多毫秒,反覆運行這個sysbench就可以將數據庫打死,建立一千個連接,300毫秒以後也會銷燬,再建立一千個連接,你的業務就會忽上忽下,通過這個腳本就可以抓到這個壓力從哪個服務器來的,哪個端口來的,然後把它搞定就可以了,這是數據庫的短連接分析。

MySQL性能診斷實踐之系統觀測工具-愛可生

第九個例子,長連接分析,除了短連接分析,還有長連接分析,哪一個業務端老在搞我的數據,老在往裡寫,總在往裡讀,搞的網絡特別慢。

MySQL性能診斷實踐之系統觀測工具-愛可生

這個就可以幫大家提供這樣的一個視角,這個就是長連接分析。它有讀有寫,都在這裡,這是第九個腳本。

MySQL性能診斷實踐之系統觀測工具-愛可生

第十個例子,CPU offcpu 消耗分析。看看最後一個腳本,這個我需要介紹一下背景,什麼叫offcpu,什麼叫消耗分析,以及最終形成的圖大概是什麼樣子。


為什麼我們要對CPU的offcpu進行分析呢?

MySQL性能診斷實踐之系統觀測工具-愛可生

因為正常的情況下CPU的工作過程是這樣子的,MySQL運行在操作系統的用戶態。序運行過程中會切入到內核態, 比如說程序進行了系統調用,比較好的情況是程序可以一直佔著cpu,所以它一直都會在運行中,如果不太好的情況,比如說遇到了磁盤的IO,網絡的IO,主動的睡眠,一些鎖的阻塞,它就會陷入不佔用CPU的情況,把CPU放棄了,然後讓給了其它線程。


但是這個時候是不是意味著數據庫工作良好?如果大家對MySQL只做onCPU的分析,這個階段onCPU是0,不佔CPU,但是因為IO是阻塞的,我想知道到底是因為什麼阻塞在這,這個就叫offcpu的分析,就是MySQL從內核態開始把CPU讓出來,開始下臺的時候,我想知道它為什麼下臺,以及下臺持續了多久,然後來進行這樣的分析。

MySQL性能診斷實踐之系統觀測工具-愛可生

它最後的輸出結果是這樣的一個圖,這個圖叫火焰圖並且這是一個冷火焰圖,它的是offcpu的,大家常見的火焰圖是火焰圖, 是紅色的, 指的是oncpu的分析。我們特意把它做成了冷色的,這是offcpu的火焰圖,很顯然沒有任何一個人能讀得懂上面寫的到底是什麼。所以我來介紹一下什麼叫火焰圖,火焰圖是這樣一個過程。

MySQL性能診斷實踐之系統觀測工具-愛可生

比如說對數據庫進行採樣,進行採樣的過程中,採了四個樣,這四個樣這個地方代表數據庫的運行堆棧,然後它的運行堆棧是這樣子,這樣四個運行堆棧,然後在火焰圖上他們就會被合併成這樣子,他們四個都涉及到第一個調用是A,所以它會把A合併在一起,第二個調用有兩個是B,把B合併在一起,最後大家看到的就是這樣一個圖,這個圖變大以後,就會長成像一個火焰的樣子,所以它就是Flame Graph。


這個是火焰圖是怎麼形成的,它是通過採樣,然後把採樣合併成一張圖,然後大家在這個圖上能獲得什麼信息,獲得的信息是程序的入口可能是A,因為所有的採樣都過了A,其中B獨立運行佔了四分之一的時間,B之上C佔了四分之一的時間,大家就能從這個圖上快速的讀出這個事情。


所以如果對這個程序要進行調優的話,大家會調到哪裡,從哪裡下手調優最直接方便?B獨立運行了四分之一,C獨立運行了四分之一,E獨立運行四分之一,我們唯一知道的是調優D是沒有用的,因為D所有的時間都被E佔用了,所以調優D不管怎麼調它自己的時間是沒有佔用的,這個就是火焰圖的基本原理。

MySQL性能診斷實踐之系統觀測工具-愛可生

我們來看一個例子,這個例子是我從剛才的那個圖上截出來的,這是offCPU分析中的一部分,它佔了剛才那張圖差不多25%的左右的大小,這個堆站從下往上讀,最下面這個大家能讀懂吧,innobase:index_read, 表示引擎在讀索引樹。然後往上讀,不知道什麼意思,mvcc不知道什麼意思,無所謂,再往上讀,Btr_...to_nth_level, 表示在讀索引數的第n層,再往上讀,我buffer上面開了一個頁,它開始讀頁了,然後這個地方涉及到了fil_io, 為了讀取這個頁我開始讀文件了,然後上面do_syscall_...進行了系統調用,然後到了VFS開始真實的進行這個系統調用。


如果這個堆棧出現在整個MySQL堆棧的25%,意味著什麼呢?意味著MySQL花了25%的時間來讀頁,來從文件系統裡邊把這個頁讀出來,這個頁是幹什麼用的?這個頁是在索引中的,就即使不懂代碼,讀這些英文,大概也能分析出如果把磁盤換掉,或者是把buffer pool擴大,擴得非常大,然後開始加內存,最好的條件下能讓這個數據庫變快25%,可能能夠把這個堆棧整個消掉,這個就是火焰圖帶給大家的IO分析的方法。

MySQL性能診斷實踐之系統觀測工具-愛可生

剛才我們介紹了十個bcc相關的例子,這些例子都是現成的腳本,bcc這個工具能向大家提供的是一整套,可以觀測這個操作系統的各個方面,比如說如果有東西被OOM kill掉了,然後內存有洩露的也可以看,然後這邊有N多的其他的部分,這個基本上是我們這幾年發現的一個寶庫,大家直接調用這些腳本就可以完成很多的別人完成不了的分析,它的技術用的是eBPF,就是我們剛才介紹的系統觀測工具。大家直接在github上直接搜就行了。


4.eBPF 使用方法/限制

如果這裡邊腳本滿足不了要求, 那我們可以自己寫。這裡我們介紹一下腳本的寫法以及eBPF的限制。

MySQL性能診斷實踐之系統觀測工具-愛可生

我們拿剛才MySQL延遲分析舉例,一個MySQL上面有一千個query,這些query大概都落在哪個延遲時間裡面那張圖,為了完成這個需求, 我需要寫兩段程序,其中第一段程序是運行在內核裡邊的程序。


這段程序的邏輯是這樣的,先在query開始的時候截獲一下,讓它記錄一個時間戳,然後請求結束的時候再截獲一下記錄一個時間戳,然後把兩個時間戳相減獲得一個延遲,然後把這個延遲扔到結果集裡邊去,程序就完成了,正常思路吧。我用結束時間減開始時間,減一下得到一個延遲,然後把延遲扔到一個統計容器裡面,這個事就結束了。這是我要寫的第一個程序,是嵌到內核裡的程序,但是需要一個外殼的程序負責嵌入。

MySQL性能診斷實踐之系統觀測工具-愛可生

這個外殼程序的邏輯也非常簡單,把剛才那段內核的程序嵌到MySQL的觀測點上,嵌到內核裡面去,然後把結果集拿出來,打印出來就結束了,這是如何寫一個eBPF的腳本,大家唯一需要做的事情就是這兩個程序,然後運行一下。

MySQL性能診斷實踐之系統觀測工具-愛可生

這個程序有多長呢?這個程序就這麼長,45行,但是我中間忽略了一些部分,這些部分是負責差錯處理,它的核心就是這45行,然後大家只需要把現在的腳本拿下來抄一抄,改一改就可以完成很多的功能了。


我們來聊聊限制,這麼好的方法為什麼很多人不知道呢?

MySQL性能診斷實踐之系統觀測工具-愛可生

操作系統內核的限制,這個功能是Linux 4.4引進來的,但是在Linux 4.4上存在統計的bug,如果大家用那張分佈圖的話,會看到這個圖上數不太對,我們推薦的是Linux 4.9+,部分好用的功能是在4.13+上才開放,這個是eBPF最大的限制。怎麼辦呢?只能祝大家長壽吧!活到Linux 4.x內核能在生產環境上使用的那一天。


它的第二個最大的限制是MySQL的編譯參數,MySQL雖然在很早很早的時候,已經提供了dtrace的觀測點,這些觀測點是公用的,但是它在默認的編譯出來的官方發佈的包裡邊是不帶觀測點編譯的,所以在直接官方發佈的二進制的包裡邊是用不了這個功能的,大家需要自己編譯一下。編譯的時候需要帶這個參數,這個可能也是屬於一個比較大的限制。


所以如果大家受到限制,我們推薦換一個工具,systemtap 。

MySQL性能診斷實踐之系統觀測工具-愛可生

Linux 2.6就已經有了,但是我剛才說過,它的機制是寫一個內核模塊,這種機制其實不是特別穩定,它為了解決不是特別穩定的問題增加了若干限制,比如說能在內核中使用的內存大小有限制,採集頻率也有限制,對整個內核的性能的影響的百分比也有限制,在這些限制參數都開起來的情況下,它還是比較安全的。


但是很多觀測功能比如說offCPU的火焰圖,就必須要把這些限制關掉,一旦關掉內核就不是很穩定,所以這個工具,我沒有敢把它的缺點寫在上面因為確實是個好的工具,我們也很難說它的這個缺點是個致命的缺陷,但是不太推薦在生產環境上使用,但是在測試環境上確實是非常好玩的一個工具,如果大家用不了eBPF的話可以用systemtap來做一些診斷。這是跟限制相關的部分。

MySQL性能診斷實踐之系統觀測工具-愛可生

然後有systemtap,有eBPF,大家就想知道有沒有其它的選擇的部分,這個圖也是我偷來的,都是羊駝,就有這麼多工具,大家可以去選擇它。


至於怎麼選擇的話,大家直接谷歌一下有專門的文章教大家怎麼來選擇這些觀測工具,但是總的來說沒有一個科學的思路,就是嘗試,不停的嘗試。

MySQL性能診斷實踐之系統觀測工具-愛可生

推薦一本書,所有的這次演講裡知識的來源都來源於這本書,我們剛才說的bcc的腳本集的作者,這是他寫的書,他還做了很多神一樣的事情,強烈推薦給大家,這本書很早中文版就出版了,但是好像很多人讀過的人不是很多。

MySQL性能診斷實踐之系統觀測工具-愛可生


除了中文版的書之外,再推薦一個文檔,這篇文檔是紅帽的官方文檔,不需要紅帽企業的會員,免費可以讀,叫:Performance Tuning Guide,它在第二節介紹了操作系統各種可以用的觀測工具,覆蓋了我們的第一部分所說的所有的外部觀測工具,以及我們在中間所說的系統觀測工具,都在這上面。但是我不太喜歡這個文檔的原因是因為它很少有原理分析,而都是在說這邊有一個參數可以調,那邊有一個參數可以調,如果大家想獲取這部分的知識的話,這篇文檔的質量也是異常的高,紅帽我一直覺得是一個賣文檔順便賣操作系統的公司。

MySQL性能診斷實踐之系統觀測工具-愛可生


分享到:


相關文章: