天天看點

優化MySQL,還是使用緩存?

今天我想對一個greenfield項目上可以采用的各種性能優化政策作個對比。換言之,該項目沒有之前決策強加給它的各種限制限制,也還沒有被優化過。

  具體來說,我想比較的兩種優化政策是優化mysql和緩存。提前指出,這些優化是正交的,唯一讓你選擇其中一者而不是另一者的原因是他們都耗費了資源,即開發時間。

  優化mysql

  優化mysql時,一般會先檢視發送給mysql的查詢語句,然後運作explain指令。稍加審查後很常見的做法是增加索引或者對模式做一些調整。

  優點

  1、一個經過優化的查詢對于所有使用應用的使用者來說都是快速的。因為索引通過對數複雜度的速度來檢索資料(又名分制,正如你搜尋一個電話簿一樣,逐漸縮小搜尋範圍),而且随着資料量的遞增也能維持良好的性能。對一個未經索引化的查詢的結果做緩存随着資料的增長有時候則可能會表現得更差。随着資料的增長,那些未命中緩存的使用者可能會得到很糟糕的體驗,這樣的應用是不可用的。

  2、優化mysql不需要擔心緩存失效或者緩存資料過期的問題。

  3、優化mysql可以簡化技術架構,在開發環境下複制和工作會更加容易。

  缺點

  1、有一些查詢不能光通過索引得到性能上的改善,可能還需要改變模式,在某些情況下這對于一些應用可能會很麻煩。

  2、有些模式的更改可能用于反規範化(資料備份)。盡管對于dba來說,這是一項常用的技術,它需要所有權以確定所有的地方都是由應用程式更新,或需要安裝觸發器來保證這種變化。

  3、一些優化手段可能是mysql所特有的。也就是說,如果底層軟體被移植到多個資料庫上工作,那麼很難確定除了增加索引外一些更複雜的優化技術可以通用。

  使用緩存

  這種優化需要人來分析應用的實際情況,然後将處理代價昂貴的部分從mysql中剝離出來用第三方緩存替代,比如memcached或redis。

  1、緩存對于一些mysql自身很難優化的查詢來說會工作地很好,比如大規模的聚合或者分組的查詢。

  2、緩存對于提高系統的吞吐率來說可能是個不錯的方案。比如對于多人同時通路應用時響應速度很慢的情況。

  3、緩存可能更容易建構在另一個應用之上。比如:你的應用可能是另一個用mysql存儲資料的軟體包的前端,而要對這個軟體包做任何資料庫方面的改動都非常難。

  1、如果資料對外提供多種存取範式(例如,在不同的頁面上用不同的形式展示),那麼讓緩存過期或者更新可能會很難,同時/或者可能需要容忍已過期的資料。一個可行的替代方案是設計一套更加精細的緩存機制,當然它也有缺點,即多次擷取緩存會增加時延。

  2、緩存一個産生代價昂貴的對象對于那些未命中緩存的使用者(見優化mysql的優勢#1)而言可能會産生潛在的性能差異。一些好的性能實踐表明你應該盡量縮小使用者之間的差異性,而不僅僅是平均化(緩存傾向于這麼做)。

  3、幼稚的緩存實作無力應對一些微妙的漏洞,比如雪崩效應。就在上周我幫助了一個人,他的資料庫伺服器被多個試圖同時再生同樣緩存内容的使用者請求沖垮。正确的政策是引入一定級别的鎖來将緩存再生的請求序列化。

  總結

  一般情況下,我會建議使用者先對mysql進行優化,因為這是我認為開始階段最合适的解決方案。但長期來看,大部分應用都會有一些用例需要一定程度上同時實作以上這些方案。