Amazon Aurora 论文解读
Amazon Aurora 論文解讀
- 復制與一致性
- 計算與存儲分離架構
- 存儲引擎
- 基本操作
- Writes
- Commits
- Reads
- Replicas
- 總結
Aurora是一個OLTP的分布式數(shù)據(jù)庫。
Amazon認為隨著分布式系統(tǒng)的發(fā)展以及架構的演進,傳統(tǒng)數(shù)據(jù)庫的磁盤IO瓶頸已經(jīng)變成了計算存儲分離架構下網(wǎng)絡IO(以及事務先關的IO處理的過程)。的Aurora通過計算節(jié)點和存儲節(jié)點分離,計算節(jié)點scale up,存儲節(jié)點scale out的理念將公有云的關系數(shù)據(jù)庫產(chǎn)品推向了一個新的高度。
傳統(tǒng)關系數(shù)據(jù)庫三宗罪,擴展性、可用性和schema 變更(前兩條普適各類存儲系統(tǒng))。經(jīng)常見到的方案中,人們用分庫分表/讀寫分離等解決擴展性,用主備策略(sync/semi-sync/async/backup|restore)解決可用性,用數(shù)據(jù)重寫/提前定義多余列/json支持等解決schema變更。這些解決方案一般是業(yè)務感知的,有時也需要業(yè)務做痛苦的取舍。更不要提一些傳統(tǒng)數(shù)據(jù)庫中一些transaction操作造成的outlier對整體性能造成的巨大拖累。
基于以上考慮,Aurora將計算與存儲分離:
復制與一致性
Aurora引入了AZ(Availability Zone)來表示一個可用區(qū)(數(shù)據(jù)中心)。典型的Aurora數(shù)據(jù)分布采用3AZ,每個AZ2副本,也就是總共6AZ。復制采用Quorum協(xié)議,6個節(jié)點,寫要至少成功4個(這里隱含的限制是Vw>N/2,從而避免更新沖突),讀要至少成功3個。通過這種配置,Aurora可以容忍1個AZ外加一個副本失效(AZ+1)而不丟數(shù)據(jù)。
論文中提到了,一個分布式存儲系統(tǒng),要想提供數(shù)據(jù)的高可用性,副本的平均失效時間MTTF(Mean Time To Failure)要遠小于副本的修復時間MTTR(Mean Time To Failure),這個很好理解,如果壞的比修的還要快,那這個集群肯定無法做到不丟數(shù)據(jù)。
Aurora對此的解法是:充分縮短修復時間。為此,Aurora將數(shù)據(jù)存放在10G的Segment中。每個Segment以及其的六個副本構成一個PG(Protection Groups)當表剛被創(chuàng)建時,它只占很少的空間,隨著數(shù)據(jù)量的增加,Aurora會通過增加Segment的方式無縫擴容最大到64G。考慮在萬兆網(wǎng)卡中,10G的流量只需要10秒。這個修復時間可以說是很很短了。但是筆者認為,Aurora中肯定有類似Chunkserver的概念,一個Chunkserver中存放多個Segment,當Chunkserver出錯下線后,理論上涉及到的所有PG都需要修復(增加副本),所以應該還是要有一個Master節(jié)點根據(jù)PG修復的緊急程度分配修復的優(yōu)先級。
計算與存儲分離架構
以傳統(tǒng)關系型數(shù)據(jù)庫MySQL為例,每個sql語句都會生成對應的事務log、binlog、數(shù)據(jù),導致數(shù)據(jù)在在網(wǎng)絡上傳輸多次,還會產(chǎn)生多次落盤。Aurora的計算與存儲分離架構主要是為了優(yōu)化網(wǎng)絡IO瓶頸。Aurora中,跨網(wǎng)絡的數(shù)據(jù)流量只有redo log,計算節(jié)點將redo log下發(fā)到存儲節(jié)點之后(存儲下推),由存儲節(jié)點負責負責管控、materialization(redo log轉換為data)、checkpoint(周期性的備份數(shù)據(jù)到S3)等。通過這種方式,Aurora實現(xiàn)了the log is the database。筆者認為這里的redo log應該比mysql包含的信息要多,才能承擔起構建整個數(shù)據(jù)庫的職責
下面表格將Aurora和mysql對比,說明了Aurora的強悍性能。
另外,Aurora的存儲引擎層在Crash Recovery中不需要回放所有的某checkpoint之后的redo log,而是異步在后臺回放,當讀到對應stale數(shù)據(jù)的時候,再搜索redo log進行回放。通過這種方式,加速了Crash Recovery。Nothing is required at database startup
文章繼續(xù)講了Aurora在降低延時方面做出的努力,如下圖所示的讀寫流程,只要1、2完成就可以返回。其余全都是后臺執(zhí)行。注意,因為Quorum的NWR,所以存儲節(jié)點需要步驟4 gossip,將當前節(jié)點的日志同步到peer節(jié)點。
存儲引擎
Aurora中的每個log都會有一個遞增且唯一的LSN(Log Sequence Number),通過整個集群LSN的推進,Aurora避免了引入2PC等復雜的機制(筆者猜想這里LSN的作用類似于Paxos/Raft中的Commit Index)。由于集群采用NWR,所以理所應當?shù)臄?shù)據(jù)中會有一些空洞,這些空洞通過上面提到的gossip填充。這些空洞應該只存在于checkpoint之后。
有了LSN,就有CPL(Consistency Point LSN)來表示某個LSN已經(jīng)被commit了,我們用VCL(Volume Complete LSN),用來表示當前系統(tǒng)確定已經(jīng)commit的最大CPL。當系統(tǒng)重啟之后,需要truncate VCL以上的log。這種日志推進的策略就很明顯了。
另外處于事務的考慮,一個事務會被拆解為多個MTR(mini-transaction)。MTR約定了最小事務,MTR中的日志必需以原子的方式執(zhí)行(比如B+Tree分裂或合并相關的數(shù)據(jù)頁)。
基本操作
Writes
在Aurora中,數(shù)據(jù)庫實例向存儲節(jié)點傳遞redo日志,達成多數(shù)派后將事務標記為提交狀態(tài),然后推進VDL,使數(shù)據(jù)庫進入一個新的一致狀態(tài)。為了避免前臺事務并發(fā)執(zhí)行太快,而存儲服務的VDL推進不及時,我們定義了LAL(LSN Allocation Limit)來表示最大未commit的日志數(shù)量。通過這種方式,限制整個存儲系統(tǒng)的并發(fā)程度,防止出現(xiàn)back-pressure(這個詞在工程界出現(xiàn)的挺頻繁的,我認為其含義指繁忙系統(tǒng)中的某個瓶頸點,在這里指網(wǎng)絡帶寬和磁盤存儲帶寬,如果LAL過大,未來的某一時刻會有很多的日志同步,占用網(wǎng)絡和磁盤帶寬)
Commits
在Aurora中,事務提交是完全異步的,存儲節(jié)點將收到的事務請求放到隊列中,等待redo log 持久化之后(VDL大于某事務的LSN),就可以向客戶端通知事務執(zhí)行成功了。這種異步機制保證了工作線程不會因為事務提交等待日志推進而阻塞。
Reads
與大多數(shù)關系型數(shù)據(jù)庫一樣,讀數(shù)據(jù)首先從buffer pool中獲得,如果數(shù)據(jù)頁不存在,才會從磁盤中獲取,然后buffer pool有淘汰、下刷臟頁的機制。Aurora不一樣的是,淘汰出去的頁不會下刷磁盤,而是直接丟棄。這意味著buffer cache中頁一定是up-to-date的(mysql這個不一定,因為有change buffer),buffer pool中的被淘汰的頁,其LSN一定是小于VCL的。
正常情況下,讀操作不需要走Quorum,VDL之前的SNL可以直接讀。這個過程文中沒有細講,但是筆者認為應該會設計到一個中心化的管理PG的服務,從PG的副本中找出一個確認commit的最大的副本提供給client讀。
Replicas
在Aurora中,寫副本實例和至多15個讀副本實例共享一套分布式存儲服務(3AZ 6replica),通過這種擴展方式以較低的成本擴展了讀節(jié)點的數(shù)量。
總結
Aurora的關鍵點在于存儲和計算相分離,并且將日志下推到存儲層(傳統(tǒng)的share disk方案無法做到這點)。由于這種分離架構下,所有IO操作都是通過網(wǎng)絡,網(wǎng)絡將成為最大的瓶頸,因此Aurora集中精力優(yōu)化網(wǎng)絡以便提高系統(tǒng)吞吐能力。缺點也很明顯:它適用于read intensive的場景(只有一個寫節(jié)點)。但帶來的讀能力的優(yōu)化已經(jīng)滿足絕大多數(shù)互聯(lián)網(wǎng)業(yè)務的需求了。
總結
以上是生活随笔為你收集整理的Amazon Aurora 论文解读的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Google Spanner 论文笔记
- 下一篇: c++的线程安全静态检查