亚马逊极光崛起:我们如何设计云原生关系数据库

post-thumb

关系数据库已经存在很长时间了。数据的关系模型早在20世纪70年代就由E.F. Codd首创。支撑当今主要关系数据库管理系统的核心技术是在1980 - 1990年代开发的。必威体育精装版app官网关系数据库基础,包括数据关系、ACID(原子性、一致性、隔离性、持久性)事务和SQL查询语言,都经受住了时间的考验。这些基础使得关系数据库在世界各地的用户中非常受欢迎。它们仍然是许多公司IT基础设施的基石。

这并不是说系统管理员一定喜欢处理关系数据库。几十年来,管理关系数据库一直是一项高技能、劳动密集型的任务。这是一项需要专门的系统和数据库管理员全神贯注的任务。在保持容错性、性能和爆炸半径大小(故障的影响)的同时扩展关系数据库一直是管理员面临的一个挑战。

与此同时,现代互联网工作负载的要求越来越高,需要基础设施的几个基本属性:

  1. 用户希望一开始占用的空间很小,然后在不受基础设施限制的情况下大量增长。
  2. 在大型系统中,故障是一种常态,而不是例外。客户的工作负载必须与组件故障绝缘或面对系统故障。
  3. 爆炸半径小。没有人希望单个系统故障对他们的业务产生巨大影响。

这些都是困难的问题,解决它们需要摆脱老式的关系数据库体系结构。当Amazon面临像Oracle这样的老式关系数据库的局限性时,我们创建了一个现代的关系数据库服务,亚马逊极光

Aurora的设计保留了关系数据库的核心事务一致性优势。它在存储层进行了创新,创建了一个为云构建的数据库,可以在不牺牲性能的情况下支持现代工作负载。客户喜欢这一点,因为Aurora以十分之一的成本提供了商业级数据库的性能和可用性。自最初发布以来,Aurora一直是AWS历史上增长最快的服务。

在这篇文章中,我想让你一窥我们是如何建造极光的。我还将讨论为什么客户采用它比AWS历史上任何其他服务都要快。

关系数据库备用

考虑一下老式的关系数据库体系结构:

这个单片的关系数据库栈在过去的30-40年里没有太大的变化。虽然存在不同的向外扩展数据库的传统方法(例如,分片、不共享或共享磁盘),但它们都共享相同的基本数据库架构。没有一个能解决性能、弹性和爆炸半径等问题,因为紧密耦合的整体堆栈的基本约束仍然存在。

为了开始解决关系数据库的局限性,我们通过将系统分解为其基本构建块来重新定义堆栈。我们认识到缓存和日志层的创新时机已经成熟。我们可以将这些层转移到一个专门构建的、可扩展的、自修复的、多租户的、数据库优化的存储服务中。当我们开始构建分布式存储系统时,Amazon Aurora就诞生了。

我们挑战了关系数据库中缓存和日志记录的传统思想,重新设计了数据库I/O层,并获得了主要的可伸缩性和弹性好处。Amazon Aurora具有显著的可扩展性和弹性,因为它支持卸载重做日志、基于单元的架构、仲裁和快速数据库修复的思想。

卸载重做日志:日志是数据库

传统的关系数据库组织数据页面,当页面被修改时,必须定期将它们刷新到磁盘。为了对故障的恢复能力和ACID语义的维护,页面修改也记录在重做日志记录,以连续流的形式写入磁盘。虽然这种体系结构提供了支持关系数据库管理系统所需的基本功能,但效率低下。例如,单个逻辑数据库写会变成多个(最多5个)物理磁盘写,从而导致性能问题。

数据库管理员试图通过减少页面刷新频率来解决写放大问题。这反过来又加剧了崩溃恢复时间的问题。刷新间隔越长,意味着要从磁盘读取更多重做日志记录,并应用更多重做日志记录来重建正确的页映像。这导致了缓慢的复苏。

在Amazon Aurora中,日志就是数据库。数据库实例将重做日志记录写入分布式存储层,存储层负责根据需要从日志记录构建页面映像。数据库实例永远不必刷新脏页,因为存储层总是知道页是什么样子的。这提高了数据库的几个性能和可靠性方面。由于消除了写放大和使用扩展存储群,写性能得到了极大的提高。

例如,与运行在类似硬件上的Amazon RDS For MySQL相比,Amazon Aurora MySQL兼容版在SysBench上的写IOPS是5x。数据库崩溃恢复时间大大缩短,因为数据库实例不再需要执行重做日志流重放。存储层负责页面读取时的重做日志应用程序,从而产生一个新的存储服务,不受遗留数据库体系结构的约束,因此您可以进一步进行创新。

基于单元的体系结构

就像我之前说的,每件事都会失败。在大型系统中,组件会出现故障,而且经常出现故障。整个实例失败。网络故障会隔离大量的基础设施。由于自然灾害,整个数据中心可能会变得孤立或宕机,但这种情况并不常见。在AWS,我们为失败设计,我们依靠基于单元的体系结构在问题发生之前就解决它。

AWS有多个地理区域(20个并且还在增加),在每个区域中,我们有多个可用区域。利用多个region和区域,设计良好的服务可以经受住普通组件故障和更大的灾难,而不影响服务的可用性。Amazon Aurora将所有写操作复制到三个区域,以提供卓越的数据持久性和可用性。事实上,Aurora可以在不损失数据可用性的情况下容忍整个区域的损失,并且可以从更大的故障中快速恢复。

然而,复制是众所周知的资源密集型,那么是什么使得Aurora能够在提供高性能的同时提供健壮的数据复制呢?答案在于法定人数。

法定人数之美

每件事都在失败。系统越大,在某个地方出现故障的可能性就越大:网络链接、SSD、整个实例或软件组件。即使软件组件没有bug,它仍然需要定期重新启动以进行升级。

在执行故障转移之前阻塞I/O处理的传统方法——当存在故障组件时以“降级模式”操作——在大规模上是有问题的。应用程序通常不能很好地容忍I/O打嗝。通过适度复杂的数学,可以证明,在一个大系统中,随着系统规模的增长,退化模式运行的概率接近1。然后,还有真正潜伏的“灰色失败”问题。当组件没有完全失效,但速度变慢时,就会出现这种情况。如果系统设计没有预见到滞后,缓慢的齿轮会降低整个系统的性能。

Amazon Aurora使用仲裁来解决组件故障和性能下降的问题。写仲裁的基本思想很简单:写入尽可能多的副本,以确保仲裁读总是找到最新的数据。最基本的仲裁示例是“2 / 3”:


Vw+ Vr> V

Vw> v / 2

V = 3

Vw= Vr= 2

例如,您可能有三个物理写要执行,写仲裁量为2。在逻辑写操作声明成功之前,您不必等待所有三个操作都完成。如果某个写入失败或缓慢,也没关系,因为总体操作结果和延迟不会受到离群值的影响。这是一件大事:即使有些东西坏了,写也能成功且快速。

简单的2/3法定人数将允许您容忍整个可用区域的损失。但这仍然不够好。虽然一个区域的丢失是罕见的事件,但它并不会降低其他区域中的组件故障的可能性。对于Aurora,我们的目标是Availability Zone+1:我们希望能够容忍一个Zone的丢失和一次故障,而不损失任何数据持久性,并且对数据可用性的影响最小。我们使用4/6的法定人数来实现这一点:


Vw+ Vr> V

Vw> v / 2

V = 6

Vw= 4

Vr= 3

对于每个逻辑日志写,我们发出6个物理副本写,当其中4个写完成时,就认为写操作成功。对于每个zone有两个副本的情况,如果整个Availability zone宕机,写入仍然会完成。如果某个区域宕机并发生额外的故障,您仍然可以实现读仲裁,然后通过执行快速修复

快速修复和追赶

数据复制有不同的方法。在传统存储系统中,数据镜像或擦除编码发生在整个物理存储单元的级别上,几个单元在一个RAID阵列中组合在一起。这种方法使修理变得缓慢。RAID重构性能受阵列设备数量有限的限制。随着存储设备变大,在重建期间应该复制的数据量也会变大。

Amazon Aurora使用了一种完全不同的复制方法,基于分片和扩展架构。一个Aurora数据库卷逻辑上分为10-GiB逻辑单元(保护团体),每个保护组以六种方式复制到物理单元().单独的部分分布在一个大型分布式存储车队中。当故障发生并取出一个段时,单个保护组的修复只需要移动约10gib的数据,这是在几秒钟内完成的。

此外,当需要修复多个保护组时,整个存储车队都会参与修复过程。这就为快速完成整批维修提供了巨大的带宽。因此,在区域丢失后又发生另一个组件故障的情况下,Aurora可能会丢失给定保护组的写仲裁数秒。然而,自动启动的修复会以很高的速度恢复可写性。换句话说,极光存储能迅速自我修复。

如何以六种方式复制数据并保持高性能的写操作?这在传统的数据库体系结构中是不可能的,在传统的数据库体系结构中,整个页面或磁盘扇区都被写入存储,因为网络将被淹没。相比之下,在Aurora中,实例只将重做日志记录写入存储。这些记录要小得多(通常是几十到几百个字节),这使得在不超载网络的情况下可以实现4/6的写入仲裁。

写quorum的基本概念意味着,某些段可能不会在最初的所有时间接收所有写操作。这些段如何处理重做日志流中的间隙?Aurora存储节点之间不断地“八卦”以填补漏洞(并进行修复)。日志流推进是通过日志序列号(Log Sequence Number, LSN)管理紧密编排的。我们使用一组LSN标记来维护每个单独段的状态。

读取呢?法定人数读取是昂贵的,最好避免。客户端Aurora存储驱动程序跟踪哪些写操作对哪些段是成功的。它不需要对例程页读取执行仲裁读取,因为它总是知道从哪里获取页的最新副本。此外,驱动程序跟踪读取延迟,并始终尝试从过去证明延迟最低的存储节点进行读取。需要进行仲裁读的唯一场景是在数据库实例重新启动的恢复过程中。必须通过请求存储节点来重建初始LSN标记集。

创新的基础

许多引人注目的Aurora新特性都是由分布式的、自修复的存储架构直接实现的。举几个例子:

  • 可伸缩性:读除主数据库实例外,最多15个读副本可以在Aurora中跨多个区域供应,以实现读取可伸缩性和更高的可用性。读副本使用与主副本相同的共享存储卷。
  • 持续备份和时间点恢复:Aurora存储层将重做日志流持续透明地备份到Amazon S3。betway88体育官网您可以在配置的备份窗口内执行时间点还原到任何时间戳。不需要安排快照创建,而且当感兴趣的时间点最近的快照距离较远时,不会丢失事务。
  • 快速克隆:Aurora存储层可以快速创建卷的物理副本,而不需要复制所有页面。页面最初在父卷和子卷之间共享,在页面被修改时完成写时复制。当卷被克隆时,没有复制成本。
  • 放弃:将数据库恢复到特定时间点的快速方法,而无需从备份执行完全恢复。不小心掉了一张桌子?你可以和奥罗拉一起让时光倒流。

在Aurora存储引擎的基础上,还将出现更多的关系数据库创新。我们都进入了关系数据库的新时代,而Aurora只是一个开始。客户的反应是一致的。每个行业的领导者,比如Capital One、道琼斯、Netflix和verizon,都在将他们的关系数据库工作负载迁移到Aurora,包括MySQL和postgresql兼容版本。

想了解更多关于亚马逊极光的设计吗?

Amazon Aurora:高吞吐量云原生关系数据库的设计考虑2017年SIGMOD

Amazon Aurora:关于如何避免I/ o、提交和成员变更的分布式共识2018年SIGMOD

评论的Disqus