淺談如何對MySQL內核進行深度優化
作者介紹:簡懷兵,騰訊雲資料庫高級工程師,負責騰訊雲CDB內核及基礎設施建設;先後供職於Thomson Reuters和YY等公司,PTimeDB作者,曾獲一項發明專利;從事MySQL內核開發工作8年,具有豐富的優化經驗;在分散式存儲等領域有較豐富經驗。
MYSQL資料庫適用場景廣泛,相較於Oracle、DB2性價比更高,Web網站、日誌系統、數據倉庫等場景都有MYSQL用武之地,但是也存在對於事務性支持不太好(MySQL 5.5版本開始默認引擎才是InnoDB事務型)、存在多個分支、讀寫效率瓶頸等問題。
所以如何用好MYSQL變得至關重要,一方面需要通過MYSQL優化找出系統讀寫瓶頸,提高資料庫性能;另一方面需要合理涉及數據結構、調整參數,以提高用戶操作響應;同時還有儘可能節省系統資源,以便系統可以提供更大負荷的服務。本文將為大家介紹騰訊雲團隊是如何對Mysql進行內核級優化的思路和經驗。
早期的CDB主要基於開源的Oracle MySQL分支,側重於優化運維和運營的OSS系統。在騰訊雲,因為用戶數的不斷增加,對CDB for MySQL提出越來越高的要求,騰訊雲CDB團隊針對用戶的需求和業界發展的技術趨勢,對CDB for MySQL分支進行深度的定製優化。優化重點圍繞內核性能、內核功能和外圍OSS系統三個維度展開,具體的做法如下:
一.內核性能的優化
由於騰訊雲上的DB基本都需要跨園區災備的特性,因此CDB for MySQL的優化主要針對主從DB部署在跨園區網路拓撲的前提下,重點去解決真實部署環境下的性能難題。經過分析和調研,我們將優化的思路歸納為:「消除冗餘I/O、縮短I/O路徑和避免大鎖競爭」。以下是內核性能的部分案例:
1.主備DB間的複製優化
問題分析
如上圖所示,在原生MySQL的複製架構中,Master側通過Dump線程不斷發送Binlog事件給Slave的I/O線程,Slave的I/O線程在接受到Binlog事件後,有兩個主要的動作:
- 寫入到Relay Log中,這個過程會和Slave SQL線程爭搶保護Relay Log的鎖。
- 更新複製元數據(包含Master的位置等信息)。
優化方法
經過分析,我們的優化策略是:
- Slave I/O線程和Slave SQL線程是典型的單寫單讀生產者-消費者模型,是可以做到無鎖設計的;因此實現思路就是Slave I/O線程在每次寫完數據後,原子更新Relay Log的長度信息,Slave SQL線程讀取Relay Log的時以長度信息為邊界。這樣就將原本競爭激烈的Relay Log鎖化解為無鎖;
- 由於Binlog事件中的GTID(Global Transaction Identifier)和DB事務是一一對應的關係,所以Relay Log中的數據本身已經包含了所需要的複製元數據,所以我們可以不寫Master info文件,消除了冗餘的文件I/O;
- 於DB都是以事務為更新粒度的,因為在Relay Log文件I/O上,我們通過合併離散小I/O為事務粒度的大I/O等手段,使磁碟I/O得以大幅提升。
優化效果
如上圖所示,經過優化:左圖35.79%的鎖競爭(futex)已經被完全消除;同壓測壓力下,56.15%的文件I/O開銷被優化到19.16%,Slave I/O線程被優化為預期的I/O密集型線程。2.主庫事務線程和Dump線程間的優化
問題分析
如上圖所示,在原生MySQL中多個事務提交線程TrxN和多個Dump線程之間會同時競爭Binlog文件資源的保護鎖,多個事務提交線程對Binlog執行寫入,多個Dump線程從Binlog文件讀取數據並發送給Slave。所有的線程之間是串列執行的!
優化方法
經過分析,我們的優化策略是:
- 將讀寫分離開來,多個寫入的線程還是在鎖保護下串列執行,每一個寫入線程寫入完成後更新當前Binlog的長度信息,多個Dump線程以Binlog文件的長度信息為讀取邊界,多個Dump線程之間並行執行。以這種方式來讓複製拓撲中的Dump線程發送得更快!
效果
優化後的示意圖如下:
經過測試,優化後的內核,不僅提升了事務提交線程的性能,在Dump線程較多的情況下,對主從複製性能有較大提升。
二.主備庫交互流程優化
問題分析
如上圖所示,在原生MySQL中主備庫之間的數據發送和ACK回應是簡單的串列執行,在上一個事件ACK回應到達之前,不允許繼續發送下一個事件;這個行為在跨園區(RTT 2-3ms)的情況性能非常差,而且也不能很好地利用帶寬優勢。
優化方法
經過分析,我們的優化策略是:
- 將發送和ACK回應的接收獨立到不同的線程中,由於發送和接收都是基於TCP流的傳輸,所以時序性是有保障的;這樣發送線程可以在未收ACK之前繼續發送,接受線程收到ACK後喚醒等待的線程執行相應的任務。
效果
根據實際用例測試,優化後的TPS提升為15%左右。
三.內核功能的優化
1. 預留運維帳號連接數配額
在騰訊雲上,不時遇到用戶APP異常或者BUG從而佔滿DB的最大連接限制,這是CDB OSS帳號無法登錄以進行緊急的運維操作。針對這個現狀,我們在MySQL內核單獨開闢了一個可配置的連接數配額,即便在上述場景下,運維帳號仍然可以連接到DB進行緊急的運維操作。極大地降低了異常情況下DB無政府狀態的風險。該帳號僅有資料庫運維管理許可權,無法獲取用戶數據,也保證了用戶數據的安全性。
2. 主備強同步
針對一些應用對數據的一致性要求非常高,CDB在MySQL原生半同步的基礎上進行了深度優化,確保一個事務在主庫上提交之前一定已經複製到至少一個備庫上。確保主庫宕機時數據的一致性。
四.外圍系統的優化
除了以上提到的MySQL內核側的部分優化,我們也在外圍OSS平台進行了多處優化。例如使用非同步MySQL ping協議實現大量實例的監控、通過分散式技術來加固原有系統的HA/服務發現和自動擴容等功能、在數據安全/故障切換和快速恢復方面也進行了多處優化。
相關推薦
騰訊雲資料庫CDB for MySQL產品相關文檔MySQL資料庫設計總結
---騰訊AI專家在知乎分享經驗---
如何成為一名AI工程師,也是知乎上的一個熱門提問。3月22日晚上8點,騰訊雲技術總監朱建平將結合實踐為大家分享人工智慧常見的幾種錯誤認知,並結合具體的一個圖片識別的場景,為大家介紹人工智慧領域的演算法、軟體與硬體的一個完整的認知框架,也會試著給出一條可能的學習路徑。朱建平還是騰訊 TEG 架構平台部專家工程師,在人工智慧用于海量圖片處理、 GPU 雲化、 FPGA 應用等領域有豐富的經驗。
【歡迎報名】 知乎Live 騰訊雲總監:如何成為 AI 工程師?
此文已由作者授權騰訊雲技術社區發布,轉載請註明文章出處,獲取更多雲計算技術乾貨,可請前往騰訊雲技術社區
推薦閱讀:
※【原創】MYSQL 的那些「坑」
※12 條用於 Linux 的 MySQL/MariaDB 安全最佳實踐
※MySQL |Self Join