《Amazon Aurora: Design Considerations for HighThroughput Cloud-Native Relational Databases》SIGMOD 2017 讀後感
Amazon Aurora: Design Considerations for HighThroughput Cloud-Native Relational Databases,來自Sigmod 2017,可以在Werner Vogels Blog上下載到 (SIGMOD 官網還沒更新)。
讀下來感受:
- Aurora 是一個OLAP數據庫,最大存儲為64TB/SSD,不是為OLAP設計
- 通過將計算邏輯下推到Storage Node(非傳統意義上存儲節點),從而解決了寫與修改過程中一份數據被放大的問題
- 本身不解決分庫分表等機製,既數倉與需要過PB級數據場景並不適合Aruora
- Aurora 巧妙的地方在於,他使用了MySQL計算引擎,100%兼容了MySQL以及PG兩種數據庫100%語法,因此應用遷移成本為0,按照存儲節點適配的思路,任何開源的數據庫理論上都較快適配上來,但對於塊存儲等設備對於所有數據庫適配性而言稍差
- 在解決放大問題後,可以達到很高的寫IOPS,並且隨著SSD或其他硬件性能提升,呈線性結構
- 一份數據默認會存3個AZ,每個AZ中存儲2份,通過局部與全局Failover概率的權衡,達到盡可能少事物提交延遲與失敗概率
- Aurora完全構建在EC2(Local Storage)、LBS、VPC、S3(備份)等這些產品基礎上,並沒有單獨從物理機上研發,也印證了AWS雲產品有兩類:基礎性雲產品、以及應用層雲產品的構建思路。好處是可以將規模、多租戶隔離等問題屏蔽掉,專心研發最重要的Storage Node即可
數據庫上分布式方案
AWS傳統RDS設計
下圖是AWS RDS方案,數據庫的計算和事務使用EC2,存儲則在分布式係統中:
在雲計算場景下,一般使用塊存儲來Host數據庫服務器,既數據庫的讀寫會在多個存儲節點上進行強一致性的同步處理,帶來的好處是存儲持久性(Durbility)高。並且分布式存儲本身可以無限擴張,因此數據量不是大的問題。除此之外,一些新存儲技術的誕生,例如NVMe SSD單機提供較高IOPS設備使得分布式存儲也能在較高讀寫情況下有很強Throughput。
AURORA中存儲設計
多副本讀與寫
分布式存儲並不是萬能的,麵臨的最大挑戰則是Transaction 等 2 Phase Commit(2PC)協議對於可靠性以及延時的TradeOff。
磁盤、網絡、機櫃、機房等都有一定的ATF(年故障率),並且日常維護重啟、升級等操作會增加這類臨時不可用時間。一般采用多副本選舉來解決該問題:例如3個副本的情況下,寫必須要有2個以上(Majority)副本寫成功才可以,在讀的情況下也必須保證有2個:V-Read + V-Write> V-Copy
Aruora設計中使用了3 AZ,每個AZ 下2 Copy的設置,共計6個副本。AWS 傳統的服務,例如S3、Kinesis等都是3副本設計。這樣的設置主要從實際觀察情況出發:
- 在同一個AZ下下硬盤、節點損壞、維修等是常態。在同一個AZ下設置2 Copy可以盡可能減少這類操作對用可用性影響
- 機房級AZ問題不常發生,例如水災、火災以及天花板損壞等故障(roof failure?)
在寫入場景下6 Copy需要保證4個副本完成,在讀場景下隻要7-4=3 個副本一致就可以了
存儲塊與日常運維
- Aurora下存儲最小單位叫Segment,每個Segment大小為10GB
- Protection Group(PG)是一個邏輯單位,代表的是6個Segment
- Segment是維護與調度的最小單元,一個Segment故障時,同AZ的萬兆網絡可以在10秒內就行修複
存儲節點Segement這種設計對於日常運維比較重要,例如在熱點問題上(Heat Management),兩個實例都非常大需要進行調度,或存儲節點OS需要Patch,存儲節點的代碼需要更新,這種類似Ping-Pang升級的方式可以使得AZ級存儲節點能夠靈活配置。
存儲節點設計核心思想(隻處理LOG,部分計算下推)
AWS傳統RDS問題在於對於寫放大,用如下這張圖就能發現,在一個Master-Slave(主從熱備)RDS場景下,主節點和存儲層的交互會被放大多次:
- Replication Log
- Redo Log (臨時存儲最後N個)
- Data(最新數據庫結構數據,內存中定時Dump)
- FRM Files(這個數據量一般比較小)
假設EBS有2-Copy,則一份數據寫入/更改被放大了222 = 6 倍,如果EBS為3-Copy,這個數據約為12倍。如果有備節點也算上的話,這個數字既為24倍。直接使用分布式存儲放大非常嚴重。
搞過Hbase人應該知道,對於LSM這樣的場景,一般10MB/S原始數據寫入,後台網絡流量會達到80-100MB/S,原因也是類似,一份數據寫入後放大如下3-Redo + 3 Mem File + 3 Times Merge = 9 Origin Input
但這種模式也帶來來了好處,就是CPU會浪費得比較少,因為3-Copy隻占據IO和網絡,CPU本質上隻有一份。
Aurora提出的思路是,計算節點直接將RedoLog下推到存儲節點,每個存儲節點根據RedoLog 來構成本地(Local Segment)存儲狀態,多個存儲可靠性通過副本數來保障。每個存儲節點也可以將Segment 定時同步到S3上增加可靠性。
每個存儲節點在處理時,在處理請求,寫入本地RedoLog後既返回,以保證低延時:
存儲節點共有5個數據鏈路上的步驟:
- 接收到請求,加入內存中的隊列(主要是為了做batch commit)
- 將批量Redolog存儲到本地磁盤
- 內存中對於批量redolog進行整理,確定還有哪些沒有catchup
- 與其他副本存儲節點進行gossip,進行對齊
- (可選)將本地redolog和 snapshot data dump到S3進行備份
後台工作(2個):
- 根據redo log進行gc,刪除無用的data 和 redo log
- 本地盤做CRC進行數據檢查,以及恢複
PAPER其他部分
明白了主要差別後,其他的讀、寫、事物提交等也沒有什麼新的東西。性能測試等可以參見Paper。
最後來一張基於ELB、EC2、VPC等部署大圖:
LESSION LEARNED
- 多租戶下的數據庫訴求:大部分AWS用戶都基於AWS開發SaaS化的軟件給用戶提供服務,在Aroura上市後發現大部分用戶對多租戶下的訴求是希望能夠提供彈性擴展的數據庫(數據庫Schema一般會不變),而不是像之前認為的,在datamodel這個層麵來進行多用戶層的統一(例如salesforce)。非常多的用戶在一個小的數據庫層李擁有十幾萬的表(看起來SQL這種編程模式已經根深蒂固),他們的訴求主要在於:
- 數據庫能夠提供足夠多的並發
- 數據庫的模型能夠保留一致,但對於數據庫的請求和訪問能夠按量進行付費(原因是上線前並不能預估具體容量,這點也是例如彈性擴展dynamoDB在AWS如此受到歡迎的原因)
- 能夠在一個數據庫下,不因為某些表的訪問脈衝,引起其他表
- 對於高並發提供彈性的擴容能力:這個搞互聯網的都應該知道
- Schema轉換能力,因業務需求經常需要做數據表DDL變更
-
高可用性,以及升級能力:6 副本,單AZ內數據節點輪轉升級,這點毫不費力
產品與售賣形態分析
最後我們來看看Aurora定價形態:
數據庫的計算實例
和AWS RDS的方式類似,本質上是直接購買EC2的節點。在創建計算實例節點後,可以將資源擴展到 32 vCPU 和 244 GiB 內存更大的實例。也可以選擇按量付費模式。
存儲進行計費
最低存儲為 10GB(一個最小Segment),最大為64TB(應該是處於SSD最大本地盤的考慮)。因為存儲層是以Segment進行管理的,所以可以彈性地從 10GB 自動增長到 64 TB,而不會影響數據庫的性能。
每GB存儲為0.1$ /Month,這對於單SSD存儲而言是一個比較Fair價格,如果是默認6-Copy,則乘以6。
根據IO進行計費
價格為 $0.200 每 100 萬個請求,這個費用屬於毛利率比較高的。
IO 是由 Aurora 數據庫引擎依靠基於 SSD 的虛擬化存儲層執行的輸入/輸出操作。每一個數據庫頁麵讀取操作為一個 IO。Aurora 數據庫引擎依靠存儲層發出讀取,以獲取不在緩衝緩存中的數據庫頁麵。每個數據庫頁麵為 16KB。
Aurora 目的是消除不必要的 IO 操作,以降低成本,並確保資源可服務於讀/寫流量。隻有將事務日誌記錄推送到存儲層,完成耐久型寫入時,才消耗寫入 IO。寫入 IO 以 4KB 單位計算。例如,1024 字節的事務日誌記錄計為一個 IO 操作。然而,當事務日誌小於 4KB 時,同時寫入操作可通過 Aurora 數據庫引擎批量進行,以便優化 I/O 消耗。
最後更新:2017-05-30 21:02:15