每日最新頭條.有趣資訊

AWS是如何設計原生雲關係數據庫AmazonAurora的?

作者:亞馬遜全球首席技術官(CTO)兼副總裁 Werner Vogels,負責推動亞馬遜全球包括雲計算在內的技術創新。

關係數據庫由來已久。關係數據模型可以追溯至 1970 年代 E.F.Codd 的探索。支撐當今主要關係數據庫管理系統的核心技術是在 1980-1990 年代開發的。關係數據庫的基本要素包括數據關係、ACID(原子性、一致性、獨立性和持久性)事務、SQL 查詢語言等,都經受住了時間的考驗。憑借這些基本特點,關係數據庫贏得了全世界用戶的鍾愛。它們依然是許多公司 IT 基礎設施的基石之一。

但這並不是說系統管理員一定很喜歡處理關係數據庫。數十年來,管理關係數據庫一直都是一件對技能要求非常高的勞動密集型工作。它要求有專門的系統和數據庫管理員全神貫注。對關係數據庫進行擴展並同時保持容錯能力、性能和爆炸半徑大小(發生故障的影響),一直是管理員們面臨的一個持久挑戰。

此外,現代互聯網工作負載的要求變得越來越高,需要基礎設施具備多個關鍵的特性:

用戶希望先從小規模起步,然後再大規模增長,基礎設施不應限制他們的發展速度。

在大型系統中,故障屬於常態,而非異常。發生組件故障或系統故障時,客戶工作負載必須隔離。

爆炸半徑要小。沒有人希望單一的系統故障對他們的業務產生巨大影響。

這些問題很難處理,需要突破傳統關係數據庫架構才能解決。當亞馬遜公司面臨 Oracle 等傳統關係數據庫的局限性時,我們創建了一種先進的關係數據庫服務Amazon Aurora。

Aurora 的設計保留了關係數據庫的核心事務一致性優勢。它在存儲層進行了創新,構建了一個面向雲的數據庫,可以在不犧牲性能的前提下支持現代工作負載。客戶非常喜歡這一點,因為 Aurora 提供了商業級數據庫的性能和可用性,但成本只有後者的十分之一。從 Aurora 最初發布以來,它一直是 AWS 歷史上增長最為快速的服務。

在本博文中,我將向大家介紹了一下我們是如何構建 Aurora 的。此外,我還將討論為什麽客戶採用它的速度要比 AWS 歷史上的任何其他服務都快。

關係數據庫的重新構想

想想傳統關係數據庫的架構:

過去 30-40 年來,這種整體式的關係數據庫堆棧沒有太大改變。雖然在數據庫擴展方面存在不同的常規方法(例如,分區、無共享或共享磁盤等),但這些方法都基於同樣的基本數據庫架構。這些方法無法解決大規模性能、彈性和爆炸半徑問題,因為嚴密耦合型整體式堆棧的基本局限性依然存在。

為開始解決關係數據庫的局限性,我們重新構想了堆棧的概念,將系統分解為基本的組成要素。我們認識到緩存和日誌記錄層非常適合創新。我們可以將這些層變為一種針對性、可擴展、可自我恢復、多租戶、數據庫優化的存儲服務。在我們開始構建這個分布式的存儲系統時,Amazon Aurora 應運而生。

我們對關係數據庫中緩存和日誌記錄的傳統理念提出挑戰,重新構想了數據庫 I/O 層,收獲了極大的可擴展性和彈性優勢。Amazon Aurora 採用了卸載恢復操作日誌記錄、基於元組的架構、仲裁以及快速數據庫修複等理念,具有極佳的可擴展性和彈性。

卸載恢復日誌記錄:日誌就是數據庫

傳統關係數據庫以頁面的方式來組織組織,因此在頁面修改後,必須定期刷新到磁盤。為確保在發生故障時的彈性以及維護 ACID 語法的需要,頁面修改也將在記錄在恢復日誌記錄中,這些日誌記錄將以連續統的方式寫入磁盤。雖然這種架構提供了支持關係數據庫管理系統所需的基本功能,但卻存在效率低下的弊端。例如,單個邏輯數據庫寫入會變為多個(不超過五個)物理磁盤寫入,從而引發性能問題。

數據庫管理員會嘗試通過降低頁面刷新的頻率來消除寫入放大的問題。但這反過來又會加劇崩潰恢復持續時間的問題。刷新間隔時間越久,意味著為了重建正確的頁面映像,需要從磁盤讀取並應用的恢復日誌記錄越多。這會導致恢復速度下降。

在 Amazon Aurora,日誌就是數據庫。數據庫實例將恢復日誌記錄寫入分布式的存儲層,由存儲負責按需利用日誌記錄構建頁面映像。數據庫實例無需帥新髒頁面,因為存儲層始終知道頁面的具體內容。這從多個方面提高了數據庫的性能和可靠性。由於消除了寫入放大,並且使用了擴展存儲隊列,寫入性能得到極大的提高。

例如,按照 SysBench 基準,Amazon Aurora MySQL 兼容版的 IOPS 寫入速度 是在類似硬體上運行的 Amazon RDS for MySQL 的 5 倍。由於數據庫實例不再需要執行恢復日誌流重放,數據庫崩潰恢復時間顯著降低。存儲層負責在頁面讀取上執行恢復日誌,從而形成一個不受傳統數據庫架構限制的新存儲服務,讓您可以更進一步創新。

基於元組的架構

我曾經說過,一切都會出現故障。組件會出現故障,在大型系統中更會經常出現故障。整個實例會出現故障。網絡故障可能導致基礎設施被大面積隔離。在極少數情況下,整個數據中心可能因自然災害被隔離或丟失。在 AWS,我們采取面向故障的設計方法,利用基於元組的架構以在問題發生前解決問題。

AWS 擁有多個地理區域(20 多個),並且在每個區域內又設了多個可用區。借助這種多區域和多可用區優勢,這種設計良好的服務可在發生普通組件故障時以及更大型的災難時正常運行,不影響服務的可用性。Amazon Aurora 將所有寫入複製到三個可用區,提供優異的數據持久性和可用性。事實上,Aurora 可以承受整個可用區的丟失而不會失去數據可用性,並且可以在更大型的故障發生後快速恢復。

但眾所周知,複製是非常耗費資源的,那麽 Aurora 是如何在提供穩健的數據複製功能的同時,確保高性能的? 答案是仲裁。

仲裁之美

一切都會出現故障。系統越大,某個東西發生故障的概率越大:網絡鏈接、SSD、整個實例、軟體組件等等。即使軟體組件沒有漏洞,它仍然需要定期重啟以進行升級。

傳統方法是在執行故障轉移前阻止 I/O 處理,以及在出現故障組件時以“降級模式”運行,這種方法在大規模環境下存在很多問題。應用程序往往也不能很好地承受 I/O“打嗝”。借助略微複雜的數學,可以證明在大型系統中,隨著系統規模的增長,以降級模式運行的概率會接近 1。此外還存在一個真正潛藏的“灰色故障”問題。 這是指組件並未完全失效,而是變得運行緩慢。如果系統設計沒有預計延遲的問題,則這一短板可能導致整個系統的性能下降。

Amazon Aurora 使用了仲裁機制來解決組件故障和性能降級的問題。寫入仲裁的基本原理十分簡單:寫入盡可能多的副本以確保仲裁讀取始終可以找到最新的數據。最基本的仲裁例子是“三分之二”:

Vw > V / 2

V=3

Vw=Vr=2

例如,您可能需要執行 3 個物理寫入,寫入仲裁為 2。您無需等待所有三個寫入都完成,即可宣布邏輯寫操作已經成功。如果有一個寫入失敗或緩慢是可以接受的,因為總體操作結果和延遲不會受到此異常值的影響。這一點非常重要:即使某個東西發生故障,仍可以成功快速完成寫入。

這種簡單的 2/3 仲裁機制可讓您容忍某個可用區完全丟失。當然這還不夠。雖然丟失整個可用區是一種稀有事件,但不會降低其他可用區發生組件故障的可能性。對於 Aurora,我們的目標是可用區+1:我們希望能夠容忍一個可用區丟失,並且同時再發生一個故障時不發生任何數據持久性損失,同時對數據可用性的影響也極低。我們使用 4/6 的仲裁機制來實現這一目標:

Vw > V / 2

V=6

Vw=4

Vr=3

對於每個邏輯日誌寫入,我們發出六項物理複製寫入指令,在其中四項寫入指令完成時視為寫入操作成功。每個可用區有兩個副本,如果整個可用區丟失,寫入操作仍將會完成。如果一個可用區丟失,同時又發生了一個故障,您仍可達到讀取仲裁要求,然後執行快速修複以快速恢復寫入能力。

快速修複和彌補

數據複製的方式有多種。在傳統存儲系統中,數據鏡像或糾刪編碼在整個物理存儲單元進行,在多個單元組合在一個 RAID 陣列中。這種方法導致修複十分緩慢。RAID 陣列的重建性能受到陣列中少數設備的能力限制。隨著存儲設備變得越來越大,重建期間需要複製的數據量越多。

Amazon Aurora 使用完全不同的複製方法,這種方法基於分區和擴展架構。Aurora 數據庫卷在邏輯上分為 10-GiB 大小的邏輯部門(保護組),每個保護組以六種方式複製到物理部門(分段)中。各個分段都分散在龐大的分布式存儲隊列中。如果發生某個故障,導致一個分段丟失,單個保護組的修複只需要移動大約 10GiB 的數據,幾秒鐘即可完成。

此外,需要修複多個保護組時,整個存儲隊列都將參與修複進程。這提供了極大的帶寬,從而可以快速完成整個批次的修複操作。因此,如果某個可用區丟失並且又發生了另一個組件故障,Aurora 可能在幾秒鐘內失去給定保護組的寫入仲裁。但自動啟動的修複操作會以極快的速度恢復可寫入性。換言之,Aurora 存儲會快速自我恢復。

是如何實現以六種方式複製數據並保持高性能的寫入的? 傳統數據庫架構會將完整的頁面或磁盤扇區寫入存儲,導致網絡疲於應付,因此無法實現這一目標。與此相反,Aurora 中的實例僅將恢復日誌記錄寫入存儲。這些記錄要小很多(一般為幾十或幾百字節),可以在不造成網絡過載的情況下實現 4/6 寫入仲裁。

根據寫入仲裁的基本原理,一些片段最初可能不會始終收到所有寫入。這些片段是如何處理恢復日誌流中的缺口的? Aurora 存儲節點會在相互之間持續“閑談”以填補空白(並執行修複)。日誌流的推進會通過日誌序列號 (LSN) 管理來緊密編排。我們使用一組 LSN 標誌來維護各個獨立片段的狀態。

讀取方面是怎麽操作的? 仲裁讀取十分昂貴,最好能夠避免。客戶端 Aurora 存儲驅動器會跟蹤哪些片段的哪些寫入操作已經成功。由於它始終知道在哪裡取得最新的頁面副本,因此不需要為例行頁面讀取執行仲裁讀取。此外,驅動器會跟蹤讀取延遲,始終嘗試從過去延遲最低的存儲節點讀取。唯一需要仲裁讀取的情形是在數據庫實例重啟期間的恢復。必須通過詢問存儲節點的方式重建初始的 LSN 標誌集。

創新的基石

Aurora 的許多重要新功能都直接受益於分布式的自我恢復型存儲架構。例如:

讀取可擴展性:除主數據庫實例外,在 Aurora 中最多可以預置 15 個隻讀副本,確保了讀取可擴展性和更高的可用性。隻讀副本與主實例使用相同的分區存儲卷。

連續備份和時間點還原:Aurora 存儲層以連續、透明的方式將恢復日誌流備份到 Amazon S3。借助時間點還原功能,您可以還原到配置的備份期內的任何時間戳。無需計劃創建快照,距離需要的時間點最近的快照極遠時也不會發生事務丟失的問題。

快速克隆:Aurora 存儲層可以快速創建卷的物理副本,無需複製所有頁面。頁面最初在父子卷之間共享,頁面修改時將完成複製並寫入操作。複製卷時不會發生重複的費用。

回溯:快速將數據庫還原至特定的時間點,但無需從備份執行完整的還原操作。錯誤丟棄了表時怎麽辦? 您可以使用 Aurora 的回溯功能還原。

依托 Aurora 的存儲引擎,更多的關係數據庫創新將會很快出爐。我們已經進入一個全新的關係數據庫時代,Aurora 僅僅是開始。客戶也異口同聲表示支持。Capital One、道瓊斯、Netflix 和 Verizon 等行業領先企業正在將他們的關係數據庫工作負載遷移到 Aurora,包括 MySQL 兼容版和 PostgreSQL 兼容版。

獲得更多的PTT最新消息
按讚加入粉絲團