一、RDS MySQL
(一)雲數據庫服務
RDS MySQL是雲數據庫服務,它將MySQL的部署、運維、彈性、安全等特性封裝起來,對外提供一個數據庫實例,相對於用戶自建數據庫,雲數據庫服務具有更經濟、更專業、更高效、更可靠、簡單易用等特點,使用戶能更專注於核心業務。
- 部署:多種部署架構,滿足多可用性要求
1)可用模式:單實例/主備/三節點
2)容災能力:同城容災/異地容災
- 運維:豐富運維功能,大幅降低運維成本
1)自動運維:備份恢復/版本升級/監控報警/故障切換
2)專家服務:性能診斷/優化建議
- 彈性:靈活產品形態,滿足系統可擴展性
1)自由彈性:可按需隨時升級內存、磁盤空間,緊隨業務發展
2)只讀實例:橫向擴展數據庫讀能力
- 安全:極高安全等級,保證數據庫安全性
1)數據安全:可靠性9個9,RPO=0,秒級的數據恢復和找回
2)數據隱私:數據鏈路加密、數據落盤加密
接下來,本文會闡述如何在RDS MySQL中實現以上功能。
(二)產品邏輯
上方為RDS MySQL產品邏輯圖。
最下層為IAAS層資源抽象,包含硬件、ECS、雲盤和下虛擬網絡。資源層之上是阿里定製的AliSQL內核,這裡還有一些管控功能。再往上是安全防護,包含鏈路加密、數據加密、訪問權限控制等。
最上層的用戶控制檯是可以讓用戶操作頁面來控制數據庫的參數配置、重啟切換等。
(三)業務模型
上圖為RDS MySQL業務模型圖。
VPC表示虛擬網絡,VPC中的模塊之間網絡是互通的。
可以看到中間的實體模塊,一個可用區下面包含數個機房,RDS的主實例、備實例或者三節點的不同的節點,是在不同的可用區裡面的。
在不同可用區的原因是如果發生某個可用區故障,我們可以快速地把服務切換到另外一個可用區,這是高可用裡跨區切換的基本保證。
SLB是網絡分發,當外部用戶連接進來後,通過這個模塊自動分發到主實例。
前文提到我們有讀寫實例和只讀實例,MySQL產品提供了數據庫代理模塊。代理模塊只對用戶開放一個連接串,用戶連接進來之後,數據庫代理可以根據用戶的業務請求情況,自動分發到讀寫實例或者只讀實例。
除此之外還有一些公共組件,如密鑰管理KMS,數據備份和日誌備份的OSS,審計日誌SLS,監控數據的雲監控,還有管理模塊OpenAPI和控制檯。
整個實例上面進行操作的原子操作通過OpenAPI提供,然後控制檯調用API,進而控制整個集群。
(四)管控架構
雲數據庫管控架構分為三層,最下層為資源層,負責所有的資源的管理和調度。運維管理層包含許多功能,如備份、恢復和監控等。接入層包含控制檯、OpenAPI等。
接下看一下在這個結構下面,RDS MySQL有一些什麼特點。
(五)產品優勢
1. 經濟:IAAS層自動化和成本控制
IASS層是雲數據庫服務的基石,提供瞭如下基礎的服務。
- 資源預測
1)售賣數據分析
2)庫存分析
3)資源利用率分析
- 採購部署
1)一鍵化部署
2)新機型演進
3)DEVOPS
4)硬件加速(RDMA,25G)
- 故障 & 過保
1)主機故障檢測
2)資源爭搶問題
3)IOHang檢測
4)自動化宕機下線
5)熱遷移秒級閃斷
- 售賣
1)主備打散
2)售賣水位控制
3)資源隔離
4)資源碎片控制
2. 穩定:完整的監控探測能力和快速恢復能力
- 高可用版主備間心跳同步
- 物理機跨機架、跨ASW部署,主備跨可用區部署能力
- 三節點企業版的三機房部署容災防腦裂
- 機房級別的容災切換能力
- 實時備份保證異常情況下服務快速拉起
如上所示,對於主備實例,我們有HA探活模塊實時監控主備的健康狀態,如果主節點發生故障,可以由備節點很快地進行接管,接管動作由HA自動完成的。
如果不是主備實例,而是單實例,當遇到節點故障,可以通過OSS拉數據的方式恢復實例。
3. 彈性:數據搬遷效率的提升和雲原生能力
計算存儲結合架構的特點是本地盤宿主機動態流控,切換秒級閃斷。
計算存儲分離架構的特點是更簡潔的擴容流程,計算存儲的本地擴容,分鐘級的彈性能力。
4. 安全:最嚴格的安全合規要求
用戶數據進來後,會經過三個流程,分別是事前防護、事中保護、事後審計。
- 事前防護
1)專有網絡VPC&平滑切換能力
2)傳輸鏈路的SSL加密
3)自研AliIpFilter安全模塊
- 事中保護
1)支持本地盤TDE和雲盤加密等多種介質
2)用戶自帶密鑰加密BYOK能力
3)支持密鑰不落盤能力
- 事後審計
1)SQL審計能力
2)API操作記錄審計
二、RDS MySQL內核
接下來看一下RDS MySQL數據庫內核,在社區版的基礎上,我們做了哪些方面的優化。
(一)可診斷度量
可診斷度量即監控,可以全方位、無死角、細粒度地對RDS MySQL 數據庫監控,包括實例級、對象級和語句級。
1. 實例級別
Server + InnoDB 55 個指標
PFS.perf_statisitics 內存表
實例級別引入了Server + InnoDB 55個指標,這個輸出是PFS.perf_statisitics 內存表,可以看到整個實例級別的運行狀態。
2. 對象級別
Table statistics 是業務系統 SCALE 的數據支撐。
Index statistics 是業務系統優化 INDEX 的數據支撐。
3. 語句級別
在語句級別,當某條SQL語句,可能返回時間慢了,運行時間長了,我們可以通過一個語句級別的統計,來查看過程中的哪個步驟導致這些問題。
如上圖所示,通過這些值可以幫助我們優化SQL。
(二)穩定性提升
在業務中經常遇到穩定性的問題。當實例運行的時候,當遇到壓力大的情況,我們允許運行時間適當增加,但不希望系統出現很劇烈的波動,因此針對穩定性問題,我們根據線上遇到的情況做了各種優化,下面舉例說明。
1. Safe to Execute DDL Under High Load
下面說一下InnoDB緩存Buffer Pool的管理。
它把所有表的對象的配置放在一起管理,當我們需要做DDL操作時,需要在Buffer Pool裡把每個配置先掃描一遍,然後做相應的動作,如刷盤,做完之後才能進行下一步DDL動作。
但是當Buffer Pool比較大的時候,這個過程會比較慢。
首先影響的就是DDL語句本身,它的時間會比較長。第二是當它頻繁掃描Buffer Pool時,會對其他Session造成影響,這樣就會造成Session抖動,延遲比較大。這裡我們做了一個優化,跟蹤每個Table的每個對象配置的使用情況,然後在做相應操作的時候,可以瞬間完成。
下圖是一個測試數據,可以看到性能得到很大提升。
2. 大表異步刪除防止IO抖動
當遇到大表刪除的情況,比如一個IBD文件大小為數百GB或上T,原生社區版刪除這個表是直接刪除,這會對文件系統造成非常大的衝擊。如果這個機器上還運行了其他的應用或實例,會造成比較大的影響。
大表異步刪除防止IO抖動的特性原理也比較簡單。當刪大文件時,我們分步驟一點一點刪掉。DDL做完之後,會把IBD文件臨時管理起來,然後少量分批進行刪除,如下圖所示。
同時,我們可以實時查詢後臺 IDB file 的 truncate 過程,看到系統裡面當前有多少表在執行異步刪除。
3. BP Online Resize: Expand Or Shrink Buffer Pool Freely
Buffer Pool在調大的時候,對系統沒有什麼影響,但如果是Buffer Pool由大變小,它會對系統的運行穩定性造成很大影響。
Adjust Buffer Pool Size Dynamically By Work Load
上圖綠色的線是社區版在Buffer Pool調小時的表現,尖刺抖動非常明顯,對業務吞吐率造成巨大波動。藍色線是優化完了之後的表現,波動明顯減弱,對業務的影響大幅減少。可以看到,RDS MySQL在做Buffer Pool在線擴縮容是比較平滑的。
4. Advanced Thread Pool
MySQL默認一個Session對應一個線程,這種模式如果是在短連接或者併發比較大的場景,由於系統裡面的線程比較多,併發上線和業務性能會受到影響。
我們知道,線程池並不是適用於所有的場景,比如大SQL或大的DDL。
如上圖所示,RDS MySQL對線程池做了優化,無論業務負載是短平快的負載,還是較大SQL,或者是長鏈接與短鏈接,線程池默認打開。
Performance Stable
5. SQL Outline
當遇到業務SQL在運行過程中,可能會因為如下原因導致執行計劃並不是最優。
傳統的解決方法可能是更新表的統計信息,或者改一下SQL加一些hint,但這些方法需要修改業務語句。
RDS MySQL提供了SQL Outline,可以在線干預SQL查詢計劃的製作過程。
它的功能與hint類似,但是不需要改應用上SQL語句,可以直接通過下方這些命令,把相應的功能加進去,主要是針對一些業務不方便在線改動SQL的場景。
靈活的接口設計和持久化保證
6. Concurrency Control
如果我們在某個短時間段之內頻繁更新某一行或幾行數據後,默認情況以事務鎖的併發機制來控制併發,這種模式的排隊調度機制會對系統造成較大的額外開銷。
但是如果我們能識別出這些語句,讓這些語句排隊執行,那麼這方面的調度開銷就可以完全消除。
RDS MySQL控制SQL併發是通過添加規則的方式,這樣不需要改用戶語句,直接就把這個規則打上去,然後運行的時候,它會自動識別這些規則,並把這些規則應用上去。
方便快捷查看併發控制規則和運行情況
(三)安全性保證
1. Transparent Data Encryption
數據安全性主要是針對數據隱私,概念上就是透明加密的功能。
在RDS MySQL中,用戶可以上傳自己密鑰到阿里雲平臺,密鑰由用戶自己管理,而不是由阿里雲生成。
2. Recycle Bin
Recycle Bin表示回收站/垃圾站。
- Recycle Bin 設計
1)Drop / Truncate 對象自動回收
2)回收站對象支持 restore 還原
3)回收站可靈活設置保留時常
4)主備間可設置不同的保留週期
Recycle Bin 操作
3. Flashback Query
FlashBack Query 快速找回數據
當遇到誤操作刪除數據、不帶 Where 條件的更新、業務回檔、多語句忘記顯式開啟事務等情況,在歷史數據還在的情況下,可以通過Flashback Query迅速把數據庫的狀態恢復到之前的某一個時間點。
(四)性能提升
1. Binlog In Redo
在MySQL帶Binlog事務提交的過程中,數據落盤有兩次,Redo一次,Binlog一次。在高併發壓力較大的情況之下,這兩個Sink對IO的負載比較大,造成性能瓶頸。
優化方案是把Binlog的Sink省略掉,這會帶來一個問題,Binlog表如果不能保證及時落盤的話,最終這個數據一致性是是得不到保證的。
我們在寫Redo的時候,把Binlog的內容同時寫到Redo裡面,然後再Sink Redo,這樣就能夠保證只Sink一次Redo,Binlog的數據還是安全的。如果不是高可用模式的話,Binlog和Redo不需要開雙翼,在不影響性能和數據可靠性的前提之下,可以保證數據的安全性。
上圖為測試指標,可以看到在16和32併發的時候,性能提升非常明顯。
2. Faster Query cache
Query cache是語句級別的結果集緩存,可以理解為一條SQL過來,如果它之前已經跑過了,結果還在,我們就可以直接返回。
社區版之前有Query cache的功能,在這基礎之上我們做了幾個方面的優策略調整:
- 併發控制
調整前:全局鎖機制
調整後:無鎖 Hash
- 內存管理
調整前:內存預分配
調整後:內存靈活分配
- 緩存機制
調整前:全路徑訪問和置換
調整後:自適應訪問和置換
由於這個功能會佔用一定內存,因此係統默認不開啟。如果用戶的業務是讀寫平均或者讀操作較多,可以在控制檯開啟這項功能。
3. Logical Row ID
當InnoDB建一張表時,如果不指定組件,那麼它的數據會通過Binlog複製到備庫,之後回放的時候是進行全標掃描,導致性能很差。
InnoDB索引組織方式是一個索引組織表,即使沒有指定組件,它裡面還是會自動生成一個Row ID。以這個Row ID作為Key來組織加速,但是Row ID並沒有在Binlog裡面把Row ID的信息傳到Slave,Row ID只是一個節點內部的一個信息,只是用來組織自己的數據,主備節點之間沒有關係,我們沒辦法利用這個Row ID來當做組件來加速日誌的回放。
我們優化的主要思路就是把Row ID通過Binlog帶到備庫,備庫再去回放的時候,Row ID就可以理解為是一個PK。
目前RDS MySQL在線上的實例非常多,在上線這個功能的時候,需要兼容已有的實例,這個功能上線之後,對所有的新數據都可生效,對老數據可以自動跳過去,然後進行兼容。
(五)企業級三節點
企業級三節點模式在電商行業中應用非常廣泛,因為電商對數據是丟失零容忍的態度。
在主備模式之下,主備之間如果是以同步方式或半同步方式進行日誌同步,當遇到備節點故障,如果複製方式不降為異步的話,主節點也不能寫,否則可能造成主備數據不一致。
這個問題的根本原因是如果只有兩個節點,當一個節點故障,那麼另一個節點肯定也不能寫了。所以一個很直觀的想法就是再加節點,假如加三個節點,當這三個節點中的多數派已經寫進去了,那麼整個集群還是可以工作的,在保證數據不丟失的情況下,還要儘可能保證集群的可用性。
這種模式抽象出來就是,有三個節點,三個節點是通過一次性協議來維護節點之間的角色和狀態,然後再進行日誌的分發,在保證數據不丟失的情況之下,最大可能性的保證集團集群的可用性。
在電商行業,節點數可能大於三,這些節點部署在不同的地點,這種配置方式非常靈活,當一個節點故障,其他節點可以提供不間斷的服務,從而保證業務正常運行。