aws aurora論文觀後

引言

打算簡單分享一下自己對aurora這個產品實現方式的理解,以及一些周邊資料,方便大家學習參考。

背景知識之mysql的容災和讀寫分離痛點

從aurora推出的時間2014年開始倒推,aurora應該是至少在2013年開始設計的,在設計之初,mysql面臨的一個很大問題就是容災切換過慢。當時的兩個主流的容災方法分別是 binlog 非同步複製 以及 semisync 。

binlog非同步複製,適合一寫多讀場景,但問題是容災時會丟數據,並不適宜對數據一致性要求高的容災。

semisync,不會丟數據,但是僅適用於一主一備的架構,不適宜用於讀多寫少的場景。

所以當年對於容災類的項目一般會做成這樣:

1. 流水類的數據用semisync做同步,因為流水類數據一般讀多寫少,且對容災的一致性有更高要求,一個流水類數據的例子比如:銀行的賬單

2. 狀態類的數據用一寫多讀,因為狀態類數據的特點是一處寫入,多個機房讀取,各個機房都傾向於本地讀取,一個狀態類數據的例子比如:用戶名,用戶手機號碼等

3. 狀態類數據的業務會自行再寫一個冪等性校驗的應用或程序,保證容災前後的一致性,有的甚至允許容災前後短暫不一致,因為狀態類數據可以由日誌類數據重新計算得到

所以從前面可以看出,mysql作為單機關係型資料庫的痛點就是:要麼要讀寫,要麼要容災,沒法都要,都要就得業務作出很多額外的功能,而且對DBA在業務容災切換時的要求很高。

當然在論文中這一段寫的比較簡單,就是說mysql的replica要同步的日誌太多了,導致性能低下,參考這幅圖

背景知識之 Mysql的redo/undo log

簡單說,就是mysql在事務中會同時記錄redo log 和 undo log,以保證事務的持久性,利用了磁碟的順序寫特點,記錄數據的變化,以便在重啟時,修正磁碟數據。

aurora 關鍵設計

aurora的整個核心思想:計算存儲分離,而實現計算存儲分離的創意就是以下幾點:

1. 去掉undo log

去掉undo log的前提是什麼?其實根據資料庫經典理論,redo,undo本來就不需要同時存在,只是在單機關係型資料庫中,redo undo 同時記錄可以得到更高的性能,在aurora中,由於存儲計算分離的大設計前提,將undo去掉,可以更有利於減小計算存儲之間的交互和傳輸數據帶寬,是一筆划算的買賣。

在數據上,根據這個圖,可以看到去掉了不必要的log後,aurora可以把單次事務的io優化到<1次(後文可以看出回滾的事務壓根不記錄log)。

2. log is database

為什麼說log is database , 因為資料庫里的數據可以由記錄數據每一次事務所導致的塊變化的log計算出來,所以aurora 專門創建了一種可以根據redo log 來重建磁碟數據的節點 log service。

由於把log重建的行為下推到了log service,同時也可以加快資料庫崩潰後的重啟,單機模式下重啟的時候需要依賴資料庫自身的進程來從checkpoint 重放 log, 而這裡資料庫進程掛了一點也不影響 logservice 建數據

3. WAL in logservice

為了讓數據寫log的行為更快的返回,aurora 還在 logservice 中多加了一個非同步動作,那就是logservice 寫redo log的行為先落磁碟,然後直接返回,對應的是論文中的這張圖。

4. 加入容災

在容災上,aurora使用了比較容易實現的quorum協議,而不是現在比較火熱的raft或paxos,可能原因是工程實現上比較簡單,畢竟,我看aurora的開發周期還是比較短的,aws上也沒有性能高的paxos 或raft實現可用(考慮2014年的情況)

5. 工程實現分析

aurora在工程實現上肯定是採用了mysql的源碼包,由於log service的剝離僅限源碼包中log manage模塊部分的內容,所以源碼的改寫量不大。而在log service中根據redo log重建數據的過程肯定也是通過源碼包部分重建磁碟文件的邏輯獨立執行,所以log service中自建代碼也肯定不多,綜合來說,aurora可以算是一個魔改mysql的設計樣本了。

這樣的優勢主要是:甚至保留了mysql中的bug,兼容性方面可以做到100%兼容,至少做maxscale,tidb,mycat的同學都懂的,要做一個100%兼容mysql的資料庫或是鏈路層有多難。。可以說aurora選擇了一條非常明智的工程道路。

今年我看aurora又馬不停蹄的推出了pg的aurora版本,很顯然,pg版本也沒改多少代碼。。

aurora事務場景分析

事務場景分為dml,事務遞交,事務回滾

1. 在事務中,aurora的mysql 主節點,在dml中不需要把undo log刷盤,直接修改內存的緩存,如果需要冷數據,則直接從log service獲取(預估log service 也提供了linux fs的介面,使得使用起來和本地磁碟介面一致)

2. 在事務遞交時,將redo log刷新到 log service,由於quorum協議,刷新6個logservice中的4個即可返回

3. 事務回滾,不需要和logservice有任何交互,直接通過mysql進程將內存的緩存刷回原有狀態即可

aurora 性能數據

按照amazon論文里的說法,我感覺不能用來做決策,我去翻了一些客觀的個人或是機構的性能數據,Amazon Aurora – Looking Deeper 根據percona的分析,aurora 6個備份節點的寫入性能大約是 percona 單機寫入的七成,這個結果是比較符合理論的,雖然拿單機比主備比較流氓,當然如果是mysql 主備的semi sync,aurora就理論看,測試出來是mysql的4-5倍也不算很反常。而且aurora在容災和備庫重建上的優勢是普通mysql無論如何無法比擬的。

觀後感

這篇aurora的論文帶給我的比較大的收穫還是在aurora的工程複雜度控制上,好的設計,大量復用mysql源碼,讓aurora的實現難度和spanner不可同日而語,但是在市場競爭上,aurora卻可以通過mysql協議100%兼容這個殺手鐧,獲得中小型客戶的歡迎,做出差異化的競爭,這對於沒有google這樣完善基礎設施,成噸大牛的公司是一個好的啟示。

參考資料

【msql】關於redo 和 undo log

論文原文: allthingsdistributed.com

MySQL · 引擎特性 · InnoDB redo log漫遊

Amazon Aurora – Looking Deeper

對細節更深入的一篇分析: 雲資料庫AWS Aurora最詳解讀!


推薦閱讀:

如何解除Amazon AWS綁定的信用卡?
AWS為什麼在中國始終不能落地 ?
有哪些雲計算平台好用又實在?
目標用戶在世界不同區域,雲服務該如何選型?
Windows Azure 為何比國內其他雲服務貴這麼多?

TAG:MySQL | AmazonWebServicesAWS | 分布式计算 |