開發與維運

讓MySQL插上緩存的翅膀

阿里雲關係型數據庫RDS(Relational Database Service) MySQL 是一種高效、穩定、安全可靠、可彈性伸縮的在線MySQL數據庫服務。為了提供極具競爭力的MySQL服務,阿里雲RDS MySQL在包括內核、管理系統上都有深度的技術加強和優化,本系列文章將會逐一對RDS MySQL特性進行拆解,主要從效能、穩定性、安全三個角度分享相比開源MySQL自建核心優勢。

本文重點介紹阿里雲數據庫MySQL的內核查詢加速技術Fast Query Cache功能。

數據庫是企業的核心資產,尤其是基於互聯網業務的現代企業,較於傳統型企業,其系統的數據量和訪問量都高出很多,並且存在突峰爆發的場景。數據庫的穩定表現往往直接關係的企業業務的連續性,甚至可能關係企業生死。

1. OLTP數據庫的請求特點和優化方案

大部分的業務數據庫系統都是在線事務性(OLTP)的,究其特點,一是單次操作數據庫的關係數據量很少,如幾條記錄或者幾十條記錄;二是對數據庫的讀請求量要遠高於寫請求量,即讀寫比嚴重不平衡,如電商業務訂單系統,一條訂單隨業務推展而狀態改變約在10次,而對應的查詢次數要超過200次。所以OLTP類數據庫的資源主要消耗於對小數據量的查詢請求處理。

為了解決這種讀寫比傾斜嚴重的問題,一般會採取如下幾種方案:

方案一:擴容數據庫硬件,尤其是增加內存,我們稱之為 數據庫的Scale up的方案。對應MySQL增加Buffer Pool大小,可快速有效提升性能。

方案二:可稱之為數據庫的Scale out方案,增加數據庫讀副本,MySQL相對比較容易做到,通過建立多個只讀備庫可極大的擴充數據庫的讀請求處理能力。但本方案帶來一個問題,就是應用要實現對讀寫請求的路由識別,只將讀請求(非事務內)路由到只讀庫,否則大量寫請求路由到只讀庫後業務將會出現大量失敗,“不小心”還會導致數據寫入錯誤。另外,應用還需要關注只讀庫與源庫的數據延遲時間,時間太長一般業務都難以接受,經驗來看秒級延遲是基本要求。

方案三:對業務系統進行架構改造,做大量的解耦工作,針對核心表做成中心服務化形式對外提供服務,如阿里淘寶天貓的幾大C系統模式。該方案的核心就是引入緩存系統,一般開源如Redis系統,利用緩存承接大量的讀請求,但整體系統需要考慮緩存失效的問題,同時還要分別維護緩存和數據庫兩套系統,技術研發成本較高。

2. 開源MySQL的Query Cache方案和問題

從上述三種方案比較來看,方案三增加查詢結果集緩存是對數據庫非常理想的解決方案,這也是大型互聯網公司普遍採用的方案,但此方案畢竟要涉及不少的應用系統改造,工程量較大,故MySQL引入了一種查詢緩存技術(Query Cache)。

MySQL Query Cache的執行流程圖如下,其保存查詢返回的完整結果,當新查詢命中該緩存會立刻返回結果,跳過了SQL解析、優化和執行等複雜階段。同時Query Cache會跟蹤查詢中涉及的每個表,如果這些表發生變化,那麼和這個表相關的所有緩存都將失效。

640.png

MySQL Query Cache原理上是通過使用額外內存來節約CPU資源來達到查詢加速的目標,是一項非常實用的技術,與MySQL組合Redis方案相比,具有以下幾個優勢:

  • 應用透明,使用Query Cache可以不更改客戶端應用程序,只需要在Server端進行簡單配置,而使用Redis則需要更改客戶端應用程序。
  • 數據一致,使用Query Cache無數據同步問題,並且可以保證事務級一致性,而使用Redis則涉及數據同步,無法實現事務級一致性。
  • 成熟穩定,MySQL有成熟的事務引擎及複製技術,可以保證數據不丟失,而Redis的持久化及複製技術不夠成熟,使用Redis需要考慮到數據丟失的問題。

但開源MySQL 實現的Query Cache不夠優雅,實際應用中存在不少問題:

  • 併發處理不夠好,在多核情況下,可能併發越高性能退化越嚴重。
  • 當緩存命中率較低時,性能無提升甚至會出現嚴重退化。
  • 內存管理問題,內存利用率低並且回收不及時,造成內存浪費。
  • 當向某個表寫入數據的時候,必須將這個表所有的緩存設置為失效,如果緩存空間很大,則消耗也會很大,可能使系統僵死一段時間,因為這個操作是靠全局鎖操作來保護的。

3. 阿里雲數據庫MySQL的Fast Query Cache

阿里雲數據庫MySQL針對開源MySQL問題,通過對Query Cache重新設計,實現了一種更好的查詢緩存機制,稱為Fast Query Cache,解決了以上幾個主要問題:

  • 優化併發控制:
    取消全局鎖同步機制,並採用無鎖機制,重新設計併發場景下的同步問題,能夠充分利用多核的處理能力,保證高併發場景下的性能。
  • 優化緩存機制:
    動態檢測緩存利用率,實時調整緩存策略,解決命中率偏低或讀寫混合等場景下的性能退化問題。
  • 優化內存管理:取消內存預分配機制,採用更加靈活的動態內存分配機制,無效的內存及時回收,保證內存的真實利用率。

阿里雲數據庫MySQL Fast Query Cache 開啟方法和開源Query Cache完全一致,通過query_cache_type參數設置為“ON”打開。在實際測試中,採用4核8GB內存的機器,利用sysbench壓測,總共數據量有250MB(25張表,每張表40000條記錄),效果非常好。

1) 全部命中只讀場景

Sysbench oltp_point_select,用例中僅包括主鍵上的點查(point select),將Query Cache設為512MB,內存大於測試數據量,緩存命中率達到99%以上。

640-1.png

測試結果顯示,在較高併發的場景下,MySQL原生Query Cache併發處理性能出現較大幅度的降低,Fast Query Cache在各個併發場景下無性能降低,最高時能夠提高一倍的QPS。

2) 高命中率只讀場景

Sysbench oltp_read_only,用例中包含返回多條記錄的範圍查詢,將Query Cache設為512MB,內存才相對比較充足,命中率可以達到80%以上。

640-2.png

測試結果顯示,隨著併發數的增加,MySQL原生Query Cache的性能出現明顯的降低,Fast Query Cache的性能則會不斷提升,最高時能夠提高一倍多的QPS。

3) 低命中率只讀場景

Sysbench oltp_read_only,用例中包含返回多條記錄的範圍查詢,將Query Cache設為16MB,內存明顯嚴重不足,緩存命中率只有10%左右,內存不足時會涉及緩存項的大量淘汰,影響性能。

640-3.png

測試結果顯示,MySQL原生Query Cache的性能降低明顯,最多出現了接近50%的性能損失,Fast Query Cache優化了低命中率場景,將性能損失控制在2%以內。

4) 讀寫混合場景

Sysbench oltp_read_write,每個事務中都有對錶的更新操作,可以認為緩存基本處於失效狀態,頻繁的更新操作涉及緩存的主動淘汰,理論上會比較影響性能。

640-4.png

測試結果顯示,Fast Query Cache在讀寫混合場景下不會出現過多的性能降低,整體性能影響控制在2%以內。

4. 總結

最後,阿里雲數據庫MySQL Fast Query Cache大大增強了數據庫查詢性能,通過增加一點點的內存換取巨大的性能提升,在主要業務場景(讀場景)中性能提升達到1倍,將會取得巨大的收益,在使用方式上和開源MySQL Query Cache保持完全一致,具備領先業界的產品競爭力。

目前Fast Query Cache已經在RDS 和 雲專屬集群RDS中具備。雲數據庫專屬集群RDS,用戶100%獨佔底層物理機,且支持用戶通過彈性資源功能靈活調配數據庫實例資源佔用,這樣開啟Fast Query Cache將會再獲得一倍性能收益,結合CPU超配技術最少獲得的一倍收益,則相比於在物理機自建,專屬集群整體成本可達到後者約30%,是目前雲上企業最好的數據庫節省成本方案。

Leave a Reply

Your email address will not be published. Required fields are marked *