容易引起雪崩的兩個處理


背景

先介紹標題《容易引起雪崩的兩個處理》的第一個處理:慢查詢。上周在測試環境遇到一個慢查詢問題,雖然是測試環境,但是現象還是很讓人擔憂的:“在大量執行update操作”“已經執行1個多小時”“負載200多,基本上庫都卡死了”。把庫都要搞掛了,細思極恐啊。於是,這個事件處理的優先級即刻被升級為S級別,我們進行了點線面的梳理和分析。

現象分析

首先針對此問題做一個分析。慢查詢的原因簡單可以這么理解:公司創立之初寫的代碼,當時上線工期緊,做的比較糙(聲明:不代表公司水平)。后台有個人工查詢操作,這個操作要查詢下游,下游是異步返回結果。所以是通過異步轉同步實現的,使用了一張表,每次操作將歷史記錄標識位全部改成“已過期”,再將新結果插入到數據表中。“在大量執行update操作”指的就是批量更新標識位的操作。大概一次操作要更新幾十萬條,然后插入幾條。一次更新要執行幾十秒。

問題解決

當時同事提出要加索引解決,我第一個反應:最主要的字段只有兩個值:“已過期”、“未過期”。對這種字段加索引是不是沒什么用?結果實際測試結果是:不加這條索引十幾秒執行完的查詢和更新操作,加了索引只要幾毫秒。

原理分析

這里主要分析三個問題。

1>為什么這條索引如此管用?

先說說為什么我第一反應覺得不管用,看看某乎上的神回復:

 

先說為什么能提高查詢速度。舉個例子,假設表中有一千萬條記錄,狀態字段有0和1兩個值。某個狀態為0的記錄總數大概會有100條,那么你想查詢狀態為0的記錄時,有沒有索引影響非常大,而查詢狀態為1的記錄,則索引基本無用。如果兩種狀態的記錄數相差無幾的話,索引也基本無用。所有的關於索引的文章,建議你不要為這種字段建索引的依據,都是以值分布是均勻為前提的。但如果值分布不均勻的時候,這個建議就不一定是正確的了。當我們需要查詢的記錄恰好是分布較少的記錄的時候,值分布越是不均勻,索引就越有價值!那為什么能提高更新速度呢?

對於update/insert/delete的每次執行,字段的索引都必須重新計算更新。聽起來很慢,但是更新操作實際上是先select再update的過程,這里因為“未過期”數據條數很少,所以select效率高,然后更新是按照id進行更新,所以很快。

2>為什么慢查詢會導致庫卡死?

一般慢查詢,特別是這樣將歷史記錄標識位全部改成“已過期”的,必然會引起鎖表。這個表的相關操作會受到影響是可以理解的,但是為什么會影響到整個數據庫呢?這就涉及一個最基本的問題:資源競爭。慢查詢和慢請求一個道理,長時間占用連接不釋放、連接數是有限的,其他后到的請求要排隊。
這個問題在生產環境相對好些,因為生產環境一般都會用物理機,而且數據盤至少是SSD的。測試環境資源差很多,所以問題會更明顯。

3>負載200多是什么概念?

系統平均負載(load averages)是對當前CPU工作量的度量,被定義為特定時間間隔內運行隊列中的平均線程數。可以通過top, htop, uptime這些命令找到它們.關於負載的含義,網上最廣泛的示例,是通過橋梁的通過率來解釋的。講的真心好,所以直接「借鑒」過來,需要看原文的直接從參考引用處自行穿越。注意這里的比喻是基於單核CPU的。

系統負荷為0,意味着大橋上一輛車也沒有 

系統負荷為0.5,意味着大橋一半的路段有車

系統負荷為1.0,意味着大橋的所有路段都有車,但任然可以順次通行 

系統負荷為1.7,除了橋滿之外,在橋的入口處還有70%的車輛在等待

系統負荷為200,除了橋滿之外,在橋的入口處還有19900%的車輛在等待!不卡死才怪!

 

sql問題影響巨大,所以我們針對所有的數據表進行了梳理,排查隱患。

 

還需要梳理所有可能引起穩定性隱患的問題。這里就要引出標題《容易引起雪崩的兩個處理》的第二個處理了:遞歸。

遞歸如果深度控制不好,會產生棧溢出,也就是StackOverflowError。溢出而使得有用的存儲單元被改寫,往往會引發不可預料的后果。怎么改呢?要解決這個問題之前刷的leetcode技能就排上用場了。把遞歸算法轉化為非遞歸算法有如下三種基本方法
1、對於尾遞歸和單向遞歸的算法,可以用循環結構的算法替代
2、自己用堆棧模擬運行時棧,分析只保存必須保存的信息(因而可小幅提高時間效率),從而用非遞歸算法替代遞歸算法。
3、利用堆棧保存參數,由於堆棧的后進先出特性吻合遞歸算法的執行過程,因而可以用非遞歸算法替代遞

 

后記

89年有個電影版的《紅樓夢》,演員陣容豪華讓人咋舌。趙麗蓉演的劉姥姥、劉曉慶演的王熙鳳、傅藝偉演的薛寶釵……。很小就覺得經典電視劇版的《紅樓夢》里薛寶釵優雅端庄,頗有大家閨秀之風。看到了電影版《紅樓夢》,特別是有個名場面:寶玉管寶姐姐要她隨身掛在脖子上的金鎖來看:電視劇版的寶姐姐金鎖是掛在貼身內層的,當時寶姐姐是這樣的:寶姐姐臉微紅,轉過身去解下金鎖,又緩緩轉過來身來,微微笑着給了寶玉。電影版的寶姐姐也是金鎖是掛在貼身內層的,寶姐姐聽寶玉問他要,她不假思索、干脆利落的解下來給了寶玉。我看到這里,心里的表情是這樣的:

 

這是哪里來的英姿颯爽的女俠走錯了片場?

而在實際工作,我也經常會遇到類似的反差。咱們的每個軟件設計和代碼,周圍的人,后來的人內心都自有評價。願他們看到的是最好的我們。


推薦閱讀

編寫代碼的「八榮八恥」(上篇)

線上問題排查的四類方法

提高用戶體驗的三種技術

近期做的穩定性建設總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM