記錄一次詭異的數據庫查詢慢的調查過程

最近的一次上線突然發現系統的某些數據庫查詢偶爾會超過300ms, 正常的情況都只有100ms,我花了一段時間開始調查原因,這篇文章記錄了整個過程。

項目背景

項目提供了一個支持水平擴展的功能,擴展主要是基於擴展多數據庫來分散壓力,我就是在這個大場景下要求新增一些數據庫來環境線上的壓力。

  • 線上分爲南方和北方兩個大機房,80%的流量都在北方機房
  • 線上流量是寫多讀少,寫大概是讀的10倍量左右
  • 本次修改是爲了解決北方機房的壓力
  • 數據庫是讀寫分離的,一個寫庫,多個從庫負責讀取

那麼我做了什麼修改呢?新申請了10個寫庫,30個讀庫,把讀寫庫的配置更新到線上,將1%的流量導入到新庫中觀察一下是否有問題,沒問題的話就全量上。

系統報警了?

1%流量剛切完, 正當我覺得一切都很簡單,突然發現報表裏這部分流量的讀取耗時有些異常,經常大於300ms。我本以爲是網絡問題,但是發現同機房的其他的數據庫完全沒有問題,不得不說我當時有點慌,趕緊檢查一下讀庫的配置是否配錯地方了。。。

費了九牛二虎之力,配置貌似沒有什麼問題,我又在本地用線上的配置跑了一把,也就是本地直接連線上的數據庫跑(別噴,我知道這樣不好),加入了計算時間的日誌,運行了一下查詢和插入,耗時沒有任何異常,都是幾毫秒。關鍵這個時候,原來的流量都挺正常的,就我切走的1%流量有問題,這個時候短信和郵件報警齊刷刷的來了,崩潰!!!!

仔細觀察現象

以我多年的經驗(其實也沒有幾年哈哈哈),這個時候一定要淡定,反正只有1%的流量,只是查詢慢一點而已,並不是功能不能用,所以我可以仔細的調查一下。那這個時候我們能用到的工具有什麼呢?無非就是線上的報表,機器上的日誌。因此我們只能從這2個方面尋找突破口了:

報表

我打開查詢耗時的報表,我發現查詢的耗時並不是一直都大於300ms,有點像毛刺,一段時間一個,而且並不是所有的庫都同一個時刻查詢慢,完全隨機,但是我注意到對於同一臺數據庫而言,它的查詢慢間隔幾乎是一分鐘左右一次,聰明的小夥伴可能已經猜到是什麼原因了,我比較菜,當時沒有立刻反應過來,所以後面還做了很多工作,接着看。

日誌

看完報表後,還是沒有什麼思路,因此我只能登陸到線上的機器上看日誌了,我們有專門記錄性能的日誌,它是一分鐘刷新一次,打開後驚訝的發現裏面每分鐘都會有大量的連接數據庫的記錄,而翻看上線前幾天的日誌則沒有那麼多的連接記錄,納尼?我們不是用數據庫連接池的嗎?我也沒改過連接池的代碼呀!!正當我困惑的時候,一個詞閃現在我腦海裏,連接池!!!

罪魁禍首

還好我之前有看過數據庫連接池的配置,我記得有一個idle_time的配置,作用是如果一個數據庫連接在idle_time時間內沒有被使用則會被關閉,有了這個思路後,我就在框架代碼裏招有關這個配置的地方,果然被我找到,如果我們不提供這個配置的話,框架自動幫我們配置成1分鐘。如果數據庫連接真的一分鐘都沒有人使用的情況下,頻繁的建立鏈接是有可能的!!!此刻感覺我找到了救命稻草一般。那真的1分鐘都沒有被使用嗎?線上的qps還是很高的,不應該啊。突然反應過來現在這40個庫只有1%的流量,而且有沒有注意到,只是查詢變慢了,但是寫並沒有變慢,爲什麼?前面介紹過,我們業務的寫是讀的10倍以上,因此就算1%的流量,寫操作也有不少,而且寫庫只有10個,讀庫卻有30個,這麼計算,讀庫平均被訪問的機率是寫庫的1/30!!!難怪連接一分鐘都沒使用就關了,下次使用的時候還要重新建立連接,而建立連接是比較耗時的,而對於應用而言,它並不感知建立連接的耗時是多少,對它而言,建立連接+查詢時間就是它的查詢時間,這也能解釋爲什麼查詢慢是毛刺,而不是一直有,因爲建立好了就正常了,如果哪個時候又閒了,就會毛刺一下。

解決辦法

解決辦法很簡單,我們在代碼裏手動配置idle_time到10分鐘,上線!果然毛刺馬上沒有了,一切正常,謝天謝地!

 

歡迎關注我的個人的博客www.zhijianliu.cn, 虛心求教,有錯誤還請指正輕拍,謝謝

版權聲明:本文出自志健的原創文章,未經博主允許不得轉載

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章