MySQL性能診斷實踐之系統觀測工具

本文根據黃炎在2018年8月3日在【2018 MySQL技術交流大會 · 上海站】現場演講內容整理而成。前端

圖片描述

黃炎,愛可生研發總監,深刻鑽研分佈式數據庫相關技術,擅長業界相關MySQL中間件產品和開發,以及分佈式中間件在企業內部的應用實踐。ios

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

分享大綱:github

  1. MySQL 慢的診斷思路
  2. 系統觀測工具介紹
  3. bcc (eBPF腳本集) 使用舉例
  4. eBPF 使用方法/限制

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

首先想請問一下你們,若是遇到MySQL慢的話你們的第一印象是什麼,MySQL數據庫若是性能不行的狀況下,你們的處理手法是怎樣?segmentfault

我諮詢了一些同行, 獲得瞭如下反饋,第一反應是再試一次,第二個反應是優化一下SQL,第三個反應是咱們調大buffer pool,而後開始換硬件了,換一下SSD,而後實在不行了咱們找個搜索引擎問一下說「MySQL慢怎麼辦」。緩存

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

圖片描述

咱們來分析一下這些現象背後隱藏的意義:服務器

圖片描述

1.若是你們再試一次可以成功的話, 意味着你可能碰到了不可復現的外界因素的影響,致使MySQL會慢。
2.若是優化SQL能解決,就意味着SQL的執行復雜度遠遠大於它的需求複雜度。
3.若是調大buffer pool能解決,就意味着MySQL碰到了自身的某些限制。
4.若是換SSD能解決,那麼意味着服務器資源受到了必定的限制。
5.若是須要搜索引擎,意味着調優這事已經變成了玄學。網絡

因此今天我想向你們介紹的是四部份內容:

1.MySQL 慢的診斷思
2.系統觀測工具介紹
3.bcc (eBPF腳本集) 使用舉例
4.eBPF 使用方法/限制

圖片描述

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

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

第三部分,給你們介紹一個腳本集,這個腳本集是開源的,開箱即用而且能夠幫助你們快速診斷MySQL的一些問題,咱們直接使用10個例子 快速地介紹一下這個腳本集能爲咱們作到什麼。

最後,咱們介紹一下eBPF的使用方法和腳本結構。任何一個好用的東西必定有它本身的限制,不然它就太完美了,因此咱們也會介紹一下它的限制究竟是怎樣的。

1.MySQL 慢的診斷思路

圖片描述

咱們先來看第一個階段,MySQL慢的診斷思路,通常咱們會從三個方向來作:

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

1.1 MySQL 內部觀測

圖片描述

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

除了這些手段之外,你們還提出了一些亂七八糟的手段,我就不列在這了,這些是常規的一個MySQL的內部的狀態觀測的思路。除了這些之外,MySQL還陸陸續續提供了一些暴露本身狀態的方案,可是這些方案並無在實踐中造成套路,緣由是學習成本比較高。

1.2 外部資源觀測

圖片描述

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

圖片描述

1.uptime,uptime告訴咱們這個機器活了多久,以及它的平均的負載是多少。
2.dmesg -T | tail,告訴咱們系統日誌裏邊有沒有什麼報錯。
3.vmstat 1,告訴咱們虛擬內存的狀態,頁的換進換出有沒有問題,swap有沒有使用。
4.mpstat -P ALL,告訴咱們CPU壓力在各個核上是否是均勻的。
5.pidstat 1,告訴咱們各個進程的對資源的佔用大概是什麼樣子。

圖片描述

咱們來看一下後五條:

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

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

1.3 外部需求改造

圖片描述

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

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

圖片描述

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

圖片描述

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

圖片描述

第三步,會教你們直接把子查詢拿掉,而後轉成這樣一個SQL,這個就叫業務改造,先後三個SQL的成本都不同,把關聯子查詢拆掉的成本,拆掉之後SQL會跑得很是好,但這個SQL已經不能良好表義了,只有在診斷到SQL成本比較高的狀況下才建議你們使用這種方式。

爲何它可以把一個關聯子查詢拆掉呢?

圖片描述

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

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

第一,MySQL自己提供了不少命令來觀察MySQL自身的各種狀態,你們從上往下檢通常能檢到SQL的問題或者服務器的問題。

第二,從服務器的角度,咱們從巡檢的腳本角度入手,服務器的資源就這幾種,觀測手法也就那麼幾種,咱們把服務器的資源所有都觀察一圈就能夠了。

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

2.系統觀測工具介紹

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

圖片描述

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

圖片描述

第一,系統觀測工具的數據源來自於哪裏;
第二,數據採集過程,由於採集的是系統的運行情況,因此到底如何採集這是一個難點;
第三,應該怎麼看數據,是用圖來看,仍是用表來看,它就叫數據處理前端;

圖片描述

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

圖片描述

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

圖片描述

第三步,數據處理前端,前端裏邊經常使用的也是perf和ftrace。若是你們對perf很熟悉的話會知道perf出來的數據是一個樹形的數據,並能夠跟這棵樹進行交互,好比說: 查看某個函數運行了多久,哪個函數的時間最長,這個是數據處理前端。

圖片描述

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

圖片描述

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

圖片描述

第二,你們經常使用的perf,原理是操做系統提供了一個系統調用能夠將數據寫到一個緩存中, 而後客戶端把這些數據端抽取出來而後呈如今顯示器上。這個是perf的運行原理。

圖片描述

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

圖片描述

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

這是四種觀測工具的不一樣。

爲何要介紹這四種觀測工具的不一樣,是由於你們在選取觀測工具的時候就知道大概怎麼選。

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

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

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

對系統侵入性最強的應該是eBPF,由於它直接將一根代碼嵌入到系統裏邊去作,最不穩定的應該是System Tap,由於它是系統的一個模塊, 又提供了很是複雜的功能。

圖片描述

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

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

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

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

圖片描述

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

圖片描述

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

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

圖片描述

咱們再來看另一種壓力,我下了一個select+insert的混合壓力在一個數據庫裏,它的圖又變了,它呈現了一個很是好的雙峯圖,我將兩個峯值用另一種顏色標明,這兩個峯值的意思是頗有可能有混合壓力在一個數據庫裏,或者是上面的這部分壓力是命中了某些緩存,而下面的某些壓力是因爲沒有命中緩存,致使這部分請求更慢一些, 造成另外一個峯值,因此你們經過這種峯值分析能夠看到數據庫大概的一個運行狀態。

若是能作得更好,你們能夠抽檢本身的數據庫而後作環比圖,好比說今天和昨天一樣的時間,一樣的業務壓力下對數據庫的延遲進行分析,若是數據庫的延遲峯一直在日後延,就意味着數據庫的狀態在變得更糟糕一些。這是bcc第一個能作的事情,須要再次強調的是它開箱即用直接下載過來就可使用。

圖片描述

第二個例子,MySQL的慢查詢,MySQL自己提供很好的慢查詢,我幹嗎要用另一個機制來獲取MySQL的慢查詢呢?

圖片描述

咱們先看一下它的輸出,其實跟MySQL自己的慢查詢還要再簡單一些。那麼咱們爲何要用另一種方式來獲取慢查詢呢?

圖片描述

由於它能作到這些事情,而MySQL的慢查詢可能很難作,與MySQL的慢日誌相比, 它能夠低成本地完成:

  1. 獲取少許慢查詢
  2. 獲取某種模式的慢查詢
  3. 獲取某個用戶的慢查詢

好比說獲取少許的慢查詢,爲何是少許呢?由於咱們不肯定如今的線上延遲是多少,慢查詢只開一秒可能日誌瞬間就被堆上去,性能就會下來,可是若是慢查詢開個十秒左右,沒有請求在這個區間命中,因此要一點一點的去調這個值,好比說線上1%的最慢的查詢可以命中,可是在這個腳本里面,能夠取必定區間的最大的幾個查詢把它拎出來。

經過腳本還能夠命中某種模式的慢查詢, 好比說咱們只關心update的慢查詢, 那麼獲取select的結果就沒有太大的意義,或者是我必定要獲取某一些特定表的相關的查詢,我均可以經過腳原本作。

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

圖片描述

以後的幾個例子都跟IO相關,因此我引用了另一篇文檔,這篇文檔是Linux IO的堆棧圖,右邊是引用的二維碼,這張堆棧圖看起來很複雜,但這個實際上是2012年畫的初版的IO堆棧圖,如今IO堆棧圖比這個要複雜不少,你們能夠在這個網址上去體驗一下。而後咱們把其中的關鍵元素抽出來,咱們看一下IO的堆棧大概是幾個層次?

圖片描述

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

圖片描述

第三個例子,VFS延遲分析,咱們對每一層均可以經過腳本對它進行IO分析,好比說我能夠對VFS作延遲分析。

圖片描述

對VFS作延遲分析,這是對數據庫進行了一個寫壓力,你們能夠明顯看到一個雙峯圖,這是寫的兩個峯,是數據庫對於內核的寫壓力的反饋。

這個意味着什麼呢?這個可能意味着由於這部分的寫是命中了操做系統文件系統的緩存,而下面這部分寫是真正的寫穿到設備的,因此他們倆的延遲不同,這是一個典型的雙峯圖,你們須要把兩個峯拆開來去行這樣的分析。

換一個說法,若是寫壓力都集中在這裏,而沒有第二個峯的狀況下,需不須要去更換物理設備?有可能不須要,由於全部的東西都命中了操做系統的緩存。

圖片描述

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

圖片描述

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

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

圖片描述

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

圖片描述

第五個例子,塊設備的延遲分析,爲何要補充一個塊設備的延遲分析呢?由於從剛纔的這些延遲分析上,延遲都是帶有操做系統緩存的影響的,而經過這個腳本能夠看出真實下到設備上的延遲是多少。

圖片描述

這是一個下到設備上的壓力的狀況, 大部分的延遲在32微秒到64微秒之間,我也不知道這個設備是好仍是很差,作IO壓力的時候很難經過絕對值去判斷這個事是好仍是很差,你們須要經過環比得出正確的結論。

![圖片描述

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

那這個圖到底有沒有問題呢?這個圖沒有什麼太大的問題,由於它的count很小。它真實的select下在到設備上的讀只有五個請求,這五個請求裏邊明顯有三個比其它的兩個延遲要高一些,這個事兒不值得分析。大部分的請求所有都被InnoDB的buffer和操做系統的Cache所有都hold住了,因此這個事情是不值得分析的,你們經過這個圖也能夠完成剛纔「需不須要更換設備, 更換設備之後MySQL會不會變得更快」的問題,在如圖的狀況下應該不會。

圖片描述

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

圖片描述

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

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

圖片描述

第七個例子,短生命週期的臨時文件檢測,這個你們不必定常見,MySQL會在某些狀況下動用臨時表, 若是SQL沒寫好就會建立臨時表,這些臨時表的生命週期很短,可是量很大,因此必定要寫文件而不能內存裏。

在這種狀況下會對操做系統形成一些壓力,而這個壓力又不太好診斷,是由於臨時文件的生存週期短,因此這個腳本能夠幫你們提供這樣的一個方案,這個方案的結果大概是這樣子。

圖片描述

我作了一個臨時表,這個臨時表活了5.3秒左右,因而它展示在了腳本的結果裏。若是你們掃描本身的線上MySQL發現這裏有大量的東西說明在大量的使用臨時表,若是IO壓力在此時比較大, 就可能受了臨時表的影響。

圖片描述

第八個例子,短鏈接分析,好一點的應用都會用鏈接池,可是咱們不少的時候沒有那麼好的運氣,老碰到那麼好的應用,因此常常業務會扔過來大量的短鏈接。

圖片描述

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

圖片描述

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

圖片描述

這個就能夠幫你們提供這樣的一個視角,這個就是長鏈接分析。它有讀有寫,都在這裏,這是第九個腳本。

圖片描述

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

爲何咱們要對CPU的offcpu進行分析呢?

圖片描述

由於正常的狀況下CPU的工做過程是這樣子的,MySQL運行在操做系統的用戶態。序運行過程當中會切入到內核態, 好比說程序進行了系統調用,比較好的狀況是程序能夠一直佔着cpu,因此它一直都會在運行中,若是不太好的狀況,好比說遇到了磁盤的IO,網絡的IO,主動的睡眠,一些鎖的阻塞,它就會陷入不佔用CPU的狀況,把CPU放棄了,而後讓給了其它線程。

可是這個時候是否是意味着數據庫工做良好?若是你們對MySQL只作onCPU的分析,這個階段onCPU是0,不佔CPU,可是由於IO是阻塞的,我想知道究竟是由於什麼阻塞在這,這個就叫offcpu的分析,就是MySQL從內核態開始把CPU讓出來,開始下臺的時候,我想知道它爲何下臺,以及下臺持續了多久,而後來進行這樣的分析。

圖片描述

它最後的輸出結果是這樣的一個圖,這個圖叫火焰圖而且這是一個冷火焰圖,它的是offcpu的,你們常見的火焰圖是火焰圖, 是紅色的, 指的是oncpu的分析。咱們特地把它作成了冷色的,這是offcpu的火焰圖,很顯然沒有任何一我的能讀得懂上面寫的究竟是什麼。因此我來介紹一下什麼叫火焰圖,火焰圖是這樣一個過程。

圖片描述

好比說對數據庫進行採樣,進行採樣的過程當中,採了四個樣,這四個樣這個地方表明數據庫的運行堆棧,而後它的運行堆棧是這樣子,這樣四個運行堆棧,而後在火焰圖上他們就會被合併成這樣子,他們四個都涉及到第一個調用是A,因此它會把A合併在一塊兒,第二個調用有兩個是B,把B合併在一塊兒,最後你們看到的就是這樣一個圖,這個圖變大之後,就會長成像一個火焰的樣子,因此它就是Flame Graph。

這個是火焰圖是怎麼造成的,它是經過採樣,而後把採樣合併成一張圖,而後你們在這個圖上能得到什麼信息,得到的信息是程序的入口多是A,由於全部的採樣都過了A,其中B獨立運行佔了四分之一的時間,B之上C佔了四分之一的時間,你們就能從這個圖上快速的讀出這個事情。

因此若是對這個程序要進行調優的話,你們會調到哪裏,從哪裏下手調優最直接方便?B獨立運行了四分之一,C獨立運行了四分之一,E獨立運行四分之一,咱們惟一知道的是調優D是沒有用的,由於D全部的時間都被E佔用了,因此調優D無論怎麼調它本身的時間是沒有佔用的,這個就是火焰圖的基本原理。

圖片描述

咱們來看一個例子,這個例子是我從剛纔的那個圖上截出來的,這是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分析的方法。

圖片描述

剛纔咱們介紹了十個bcc相關的例子,這些例子都是現成的腳本,bcc這個工具能向你們提供的是一整套,能夠觀測這個操做系統的各個方面,好比說若是有東西被OOM kill掉了,而後內存有泄露的也能夠看,而後這邊有N多的其餘的部分,這個基本上是咱們這幾年發現的一個寶庫,你們直接調用這些腳本就能夠完成不少的別人完成不了的分析,它的技術用的是eBPF,就是咱們剛纔介紹的系統觀測工具。你們直接在github上直接搜就好了。

4.eBPF 使用方法/限制

若是這裏邊腳本知足不了要求, 那咱們能夠本身寫。這裏咱們介紹一下腳本的寫法以及eBPF的限制。

圖片描述

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

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

圖片描述

這個外殼程序的邏輯也很是簡單,把剛纔那段內核的程序嵌到MySQL的觀測點上,嵌到內核裏面去,而後把結果集拿出來,打印出來就結束了,這是如何寫一個eBPF的腳本,你們惟一須要作的事情就是這兩個程序,而後運行一下。

圖片描述

這個程序有多長呢?這個程序就這麼長,45行,可是我中間忽略了一些部分,這些部分是負責差錯處理,它的核心就是這45行,而後你們只須要把如今的腳本拿下來抄一抄,改一改就能夠完成不少的功能了。

咱們來聊聊限制,這麼好的方法爲何不少人不知道呢?

圖片描述

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

它的第二個最大的限制是MySQL的編譯參數,MySQL雖然在很早很早的時候,已經提供了dtrace的觀測點,這些觀測點是公用的,可是它在默認的編譯出來的官方發佈的包裏邊是不帶觀測點編譯的,因此在直接官方發佈的二進制的包裏邊是用不了這個功能的,你們須要本身編譯一下。編譯的時候須要帶這個參數,這個可能也是屬於一個比較大的限制。

因此若是你們受到限制,咱們推薦換一個工具,systemtap 。

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

可是不少觀測功能好比說offCPU的火焰圖,就必需要把這些限制關掉,一旦關掉內核就不是很穩定,因此這個工具,我沒有敢把它的缺點寫在上面由於確實是個好的工具,咱們也很難說它的這個缺點是個致命的缺陷,可是不太推薦在生產環境上使用,可是在測試環境上確實是很是好玩的一個工具,若是你們用不了eBPF的話能夠用systemtap來作一些診斷。這是跟限制相關的部分。

圖片描述

而後有systemtap,有eBPF,你們就想知道有沒有其它的選擇的部分,這個圖也是我偷來的,都是羊駝,就有這麼多工具,你們能夠去選擇它。

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

圖片描述

推薦一本書,全部的此次演講裏知識的來源都來源於這本書,咱們剛纔說的bcc的腳本集的做者,這是他寫的書,他還作了不少神同樣的事情,強烈推薦給你們,這本書很早中文版就出版了,可是好像不少人讀過的人不是不少。

圖片描述

除了中文版的書以外,再推薦一個文檔,這篇文檔是紅帽的官方文檔,不須要紅帽企業的會員,免費能夠讀,叫:Performance Tuning Guide,它在第二節介紹了操做系統各類能夠用的觀測工具,覆蓋了咱們的第一部分所說的全部的外部觀測工具,以及咱們在中間所說的系統觀測工具,都在這上面。可是我不太喜歡這個文檔的緣由是由於它不多有原理分析,而都是在說這邊有一個參數能夠調,那邊有一個參數能夠調,若是你們想獲取這部分的知識的話,這篇文檔的質量也是異常的高,紅帽我一直以爲是一個賣文檔順便賣操做系統的公司。

我今天的全部的內容都已經呈現完了,謝謝!

PPT下載連接:github.com/actiontech/slides

相關文章
相關標籤/搜索