論文位址:https://pdos.csail.mit.edu/6.824/papers/aurora.pdf
一、Aurora概述
aurora是AWS提供的一個OLTP關系型資料庫。設計者認為核心的限制已經從計算和存儲轉向網絡,aurora通過将redo log的處理下推到存儲層,來解決此問題。aurora不僅減少網絡流量,也支援快速恢複,不丢失資料的故障轉移,容錯,自愈的存儲,并且通過高效的異步模式解決跨多個節點的持久化問題,避免昂貴的故障恢複代價。
關鍵詞:資料庫、分布式系統、日志處理、quorum模型、複制、恢複、性能、OLTP
通過存儲計算分離和複制存儲,可以是服務具有更好的彈性和伸縮性。這樣可以替換異常行為或不可通路的主機,增加副本,故障轉移,伸縮資料庫執行個體等。
aurora相比傳統資料庫有三個大的優勢:
- 通過建構容錯和自愈的存儲服務來保護資料庫免受性能變化和在網絡、存儲故障。
- 通過隻寫redo log記錄到存儲層能減少一個數量級的網絡IO
- 把許多複雜和重要的功能(如備份和redo恢複)從單次昂貴的操作變成持續的異步操作,并且分攤到分布式叢集各個節點當中
本論文主要講述三個方面:
- 在雲環境的持久化和設計一個彈性的quorum系統
- 日志處理下沉到存儲層
- 如何消除多階段的同步、崩潰恢複在分布式系統中
二、可擴充的持久化(容錯)
複制和故障
- quorum模型:Vr + Vw > V,Vw > V/2
- 存儲叢集部署在三個AZ當中,每個AZ有兩個replica
- quorum模型保證三個AZ中如果一個AZ出現故障則還可以提供讀寫能力,如果一個AZ+一個replica故障可以提供讀能力
分段存儲
為了減少故障恢複時間,aurora把storage volumn拆分成segment存儲,在不同的replica上的相同segment組成一個Protection Group,每個segment為10GB。是以一個storage volumn是由若幹PG組成,實體上PG是由挂載SSD的EC2伺服器提供服務。在一個storage volumn發生故障後,它可以并行的從其它存儲相同segment的EC2服務擷取資料,是以大大減少了資料恢複的時間。
三、日志處理下沉
通過日志處理下沉到存儲層,極大減少網絡IO的數量。
通過不同的技術手段在存儲層,減少同步等待和不必要的寫。
放大寫的負擔
- 傳統mysql複制過程的資料太多,并且都是同步的
- 從分布式系統的角度來看是4/4的quorom模型,對容錯的能力極低
下沉redo log處理到存儲層
資料庫執行個體在處理生成redo log後不再做其它操作,直接将redo log下發到存儲層,在存儲層進行page的計算。并且資料庫執行個體在儲存成功redo log後即可傳回,存儲層可以按需進行後續的計算和寫入page,對于存儲引擎來說:log就是資料庫。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNCM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2csoXRq5ENrR0TwUkeYhnRzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcuYTMxIjNzATMwMDOwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
好處:
- 提高了整體服務的吞吐(35倍事務處理)
- 提高可用性,通過減少錯誤恢複、消除由例如檢查恢複、背景寫資料頁、備份等帶來的抖動
對于崩潰恢複:
在傳統關系資料庫,在系統崩潰後會checkpoint并且確定持久化的redo log被實施。在aurora中持久化的redo log分布在存儲層,當收到一個請求後會計算page是否存在,如果不存在則apply redo log,這樣在啟動時不必做任何其它操作。
存儲層服務設計要點
存儲層核心的設計原則是最小化前台等待的時間,是以把主要的存儲層的多數任務移到背景處理。
存儲節點主要的執行流程:
- 接收redo日志并儲存到記憶體隊列裡
- 持久化日志并傳回ack
- 組織日志記錄,并确認丢失的日志
- 使用gossip協定與其它peer交換日志
- 合并redo log生成新的page
- 間隔的生成日志和資料快照儲存進S3
- 間隔的回收舊版本資料頁
- 驗證CRC
四、THE LOG MARCHES FORWARD
四個問題:
- 日志如何從資料庫生成
- 如何不使用2PC來高效實作一緻性
- 如何避免崩潰恢複時昂貴的redo處理
- 如何維護副本狀态
異步處理
每個log有一個LSN,由資料庫單調自增産生,使用LSN可以避免使用2PC來保證一緻性,并且過程是異步的。
存儲服務确定最高的VCL(volume complete LSN),當存儲恢複過程中,高于VCL的log将被截斷。資料庫可以通過設定CPL,即人為設定截斷點,第一個小于VCL的CPL稱做VDL。例如,如果目前最高的LSN是1007,設定CPL為900、1000、1100,那麼VDL為1000,那麼我們人為完成到1007,但是隻持久化到1000。
如果沒有設定CPL,那麼每個LSN則可以看作是CPL。
實際上,資料庫和存儲服務的互動如下:
- 每個資料庫層的事務拆成多個小的順序的事務(MTR)并被原子的執行
- 每個mini-transaction都是由多個連續的日志記錄組成
- 在mini-transaction中最後的log則是一個CPL
Normal Operation
Writes
資料庫收到write quorum的ack後會推進VDL。由于資料庫可能同時有很多活躍的事務,那麼資料庫在配置設定LSN時,會不超過VDL+LAL的和(LAL是LSN配置設定數量限制,目前是10m),保證資料庫服務的LSN不會超前存儲服務的LSN太多。目的是當存儲服務或者網絡故障,前台的請求不會繼續進來。
每個segment隻能看到volume上一部分log(每個segment加起來才是整個volume)。每個log有前一個log的連結,每個segment有一個最大的LSN稱為SCL(segment complete LSN)。SCL用來追蹤segment的完整性,每個存儲節點通過gossip協定來查找和交換缺失的日志。
Commits
在aurora中事務的送出完全是異步的。當一個事務請求進來,将commit LSN放進事務清單裡然後執行其它的工作。當VDL大于commit LSN時,表示這個事務已經送出完成,可以回複用戶端ok了。這種異步的方式大大提高了系統的吞吐
Reads
在傳統資料庫中,隻有通路的page不再cache中才會産生IO,并且如果cache滿了,會有刷髒頁的過程。
aurora中不會有刷髒頁的過程,因為它直接丢棄髒頁,它保證緩存都是最新的資料。實作方式是将目前page LSN大于等于VDL的page删除掉,這樣可以確定所有page都已經持久化到日志。
Replicas
在aurora中,一個寫副本和15個讀副本挂載在一個共享存儲的volumn上。寫副本生成redo log後會發送給所有讀副本,每個讀副本會實施這些redo log,實施過程中如果需要的page在cache中則正常實施,如果不再cache中則丢棄。讀副本實施redo log遵守兩個規則:a.僅僅那些小于等于VDL的LSN會被實施,b.這些log必須以mini-transaction為最小機關,確定整個資料庫的一緻性。通常讀副本會比寫副本會有20ms的延遲。
Recovery
傳統資料庫的恢複使用類似ARIES的協定,根據WAL。資料庫故障後會通過checkpoint方式來重放日志恢複資料。是以恢複的時間和資料庫檢查的頻率相關系。
aurora将重放的過程放到了存儲節點,并且完全背景操作,即使在100K tps的情況下,也能10秒恢複。資料庫在當機重新開機後,存儲執行個體與read quorum個存儲節點通訊,保證讀到的資料是最新的,并重新計算VDL,超過VDL的部分日志都被截斷丢棄。
五、PUTTING IT ALL TOGETHER
aurora整體架構