当前位置:   article > 正文

Aurora论文分析——Lec10_论文aurora

论文aurora

前言

Aurora特点:1.计算存储分离,redo日志下移到存储层。2.“日志即数据库”即:redo日志包含所有数据,因为它可回放。3.基于quorum6副本,写4/6,读3/6。4.分片存储来降低故障修复时间(MTTR)——10G。

一、Aurora简介

1.Aurora是一个AWS上的分布式OLTP(在线事务处理)关系数据库,高性能、高可靠。而本文的一个重要观点是:性能瓶颈从CPU和存储变成了网络,因此将计算与存储分离
(1)数据库实例(计算层)和存储层松耦合。
(2)数据库实例(计算层)仍包含大部分核心功能,如查询、事务、锁、缓存、访问接口、undo日志等。
(3)redo日志相关功能下移到存储,如日志处理、故障恢复、备份还原等。
2. 这样的优势有:
(1)底层存储层本身是分布式存储服务,可应对故障
(2)数据库实例(计算层)只往下面存储层写redo日志,降低两层之间的网络压力
(3)部分核心功能(故障恢复、备份还原等)移到存储层,可后台异步执行,不影响前台任务
3.论文主要包括三大块:
(1)如何在云上实现持久化,基于quorum模型,使存储层能弹性容错(第三部分)
(2)如何将计算层下层的日志处理功能转移到存储层上(第四部分)
(3)如何在分布式存储中消除多阶段同步,并避免开销巨大的崩溃恢复和检查点操作(第五部分)
4.论文内容是关于如何让一个高性能高可靠的数据库作为云基础架构。
5.在处理事务的速度上,Aurora宣称比其他数据库快35倍。
6.Amazon首先使用的是自己的通用存储,但是后来发现性能不好,然后就构建了完全是应用定制(Application-Specific)的存储,并且几乎是抛弃了通用存储。

二、Aurora诞生背景

1.EC2(Elastic Cloud 2)

(1)最早的时候,Amazon提供的云产品是EC2,它可以帮助用户在Amazon的机房里和Amazon的硬件上创建类似网站的应用。在一个服务器上,有一个VMM(Virtual Machine Monitor),还有一些EC2实例,其中每一个实例都出租给不同的云客户。
(2)最早的时候EC2用的都是服务器的本地硬盘,每个EC2实例会分到本地盘的一小部分。
在这里插入图片描述
(3)对于无状态的web服务器,EC2实例是很完美的。但是对于数据库,当服务器宕机时,因为数据存储在EC2实例所在的服务器本地硬盘,就会造成数据丢失。
虽然Amazon会采用S3块存储服务对数据库快照存储,并基于快照来实现故障恢复,但是这种定期的快照意味着你可能会损失两次快照之间的数据。

2.EBS(Elastic Block Store)

(1)EBS是一个容错的且支持持久化存储的服务。
从EC2实例来看,EBS就是一个硬盘。
在实现上,EBS底层是一对互为副本的存储服务器,这两个EBS服务器会使用上一篇论文中的Chain Replication进行复制。(写请求第一个到第二个,读请求从第二个EBS服务器读)
所以,现在你运行了一个数据库,相应的EC2实例将一个EBS volume挂载成自己的硬盘。当数据库执行写磁盘操作时,数据会通过网络送到EBS服务器。
在这里插入图片描述
(2)EBS运行数据库时,传输数据会产生大量的网络流量。
Aurora花费了大量的精力来降低数据库产生的网络负载。
(3)EBS的容错性不是很好。出于性能的考虑,Amazon总是将EBS volume的两个副本存放在同一个数据中心/AZ(Availability Zone)。

注:在Amazon的术语中,一个AZ就是一个数据中心。

三、可伸缩的持久性

本节介绍quorum模型,并介绍存储分段。
Aurora将两者结合,实现持久性、可用性、少抖动,并解决大规模存储的相关问题。

1.复制及其相关的错误

大规模下,错误经常发生,所以需要复制以容错。
(1)Auroma使用基于quorum的复制协议

  • 记副本个数为V个,读需要Vr个副本的投票,写需要Vw个副本的投票
  • 首先要保证必有一个副本是最新的,即Vr+Vw>V
  • 写需要有多数的同意,防止写冲突,即Vw>V/2
    在这里插入图片描述
    客户端如何知道从R个服务器得到的R个结果中,哪一个是正确的呢?
    在Quorum系统中使用的是版本号(Version)。所以,每一次执行写请求,你需要将新的数值与一个增加的版本号绑定。之后,客户端发送读请求,从Read Quorum得到了一些回复,客户端可以直接使用其中的最高版本号的数值。
    (2)常用配置下,Aurora通常将副本分布到3个AZ(可用区),每个AZ有2个副本,即V=6,然后设置Vr=3,Vw=4。这样它可以:
  • 一个AZ整个故障,依旧不影响写服务(AZ)
  • 一个AZ整个故障,另一个AZ一个副本故障,依旧不影响读服务,且不丢失数据(AZ+1)
    在这里插入图片描述

2. 分片存储

(1)以上面的AZ+1故障为例,我们需要保证两个完整AZ故障的概率足够低,才能保证quorum有效。
而故障频率(MTTF)不可知,因此需要降低故障修复时间(MTTR),从而降低2个AZ同时故障的概率。
解决方式是分片存储:

  • 副本根据固定大小分片(如10GB)
  • 每个分片被6路复制到3个AZ上,每个AZ有2个,这6个分片组成一个保护组(PG)
    例:如果一个数据库需要20GB的数据,那么这个数据库会使用2个PG(Protection Group),其中一半的10GB数据在一个PG中,包含了6个存储服务器作为副本,另一半的10GB数据存储在另一个PG中,这个PG可能包含了不同的6个存储服务器作为副本。
    你可以将磁盘中的data page分割到多个独立的PG中,比如说奇数号的page存在PG1,偶数号的page存在PG2。如果可以根据data page做sharding,那是极好的。
    在这里插入图片描述
    Aurora存储由若干个PGs构成,而PGs由EC2+SSD存储节点构成。
    分片后,每个分片就是一个故障单位,恢复时只要恢复指定分片即可,速度会非常快。这降低了MTTR,从而提高了可用性。
    (2)出现故障时重建副本策略
    Aurora实际使用的策略是,对于一个特定的存储服务器,它存储了许多Protection Group对应的10GB的数据块。对于Protection Group A,它的其他副本是5个服务器。
    这个存储服务器还为Protection Group B保存了数据,但是B的其他副本存在于与A没有交集的其他5个服务器中。类似的,对于所有的Protection Group对应的数据块,都会有类似的副本。
    这种模式下,如果一个存储服务器挂了,假设上面有100个数据块,对于每一个数据块,我们会从Protection Group中挑选一个副本,作为数据拷贝的源。这样,对于100个数据块,相当于有了100个数据拷贝的源。之后,就可以并行的通过网络将100个数据块从100个源拷贝到100个目的。
    在这里插入图片描述
    这就是Aurora使用的副本恢复策略,它意味着,如果一个服务器挂了,它可以并行的,快速的在数百台服务器上恢复。

3.弹性容错的运维优势

Aurora能对长短故障都有弹性,这基于quorum协议和分段存储。
因此,系统可灵活应对故障,且运维方便,如:

  • I/O压力过大:可剔除某个分段,通过迁移热点数据到冷节点上,quorum机制可很快地修复
  • 系统更新导致的不可用:可临时将节点剔除,待完成后再加入到系统
  • 软件更新:同系统更新
    以上操作,都是分片粒度滚动进行,对外完全透明。

四、日志即数据库

“日志即数据库”即:redo日志包含所有数据,因为它可回放。

即数据库就是redo日志数据流

本节介绍Aurora的计算存储分离架构是如何体现这个思想的。

1.写放大问题

(1)关系型数据库(Amazon RDS)

在MySQL基础上,结合Amazon自己的基础设施,Amazon为其云用户开发了改进版的数据库,叫做RDS(Relational Database Service)。论文中的Figure 2基本上是对RDS的描述。
RDS是第一次尝试将数据库在多个AZ之间做复制。
对于RDS来说,有且仅有一个EC2实例作为数据库。这个数据库将它的data page和WAL Log存储在EBS,而不是对应服务器的本地硬盘。当数据库执行了写Log或者写page操作时,这些写请求实际上通过网络发送到了EBS服务器。所有这些服务器都在一个AZ中。
在这里插入图片描述
每一次数据库软件执行一个写操作,Amazon会自动的,对数据库无感知的,将写操作拷贝发送到另一个数据中心的AZ中的另一个EC2实例,AZ2的副数据库会将这些写操作拷贝AZ2对应的EBS服务器。
在这里插入图片描述
在RDS架构中,即在下图Figure 2中,每一次写操作,例如数据库追加日志或者写磁盘的page,数据除了发送给AZ1的两个EBS副本之外,还需要通过网络发送到位于AZ2的副数据库。副数据库接下来会将数据再发送给AZ2的两个独立的EBS副本。之后,AZ2的副数据库会将写入成功的回复返回给AZ1的主数据库,主数据库看到这个回复之后,才会认为写操作完成了。
RDS每一次调用写操作,需要等待4个服务器更新完成,并且等待数据在链路上传输。
如论文中表1的性能描述
在这里插入图片描述
这种Mirrored MySQL比Aurora慢得多的原因是,它通过网络传输了大量的数据。

(2)mirrored MySQL总结

在传统关系数据库跨数据中心的复制场景下,会产生非常多的磁盘和网络I/O,性能糟糕。
下图以MySQL为例:

  • AZ1和AZ2各部署MySQL实例,进行同步镜像复制
  • 底层存储使用EBS,每个EBS还有一个自己的镜像
  • 另部署S3执行redo日志和bin log的归档,以实现基于特定时间点的恢复
    在这里插入图片描述
    那么一个写操作需要5步,因此性能很差。以分布式观点,它是一个4/4的write quorum(4个EBS镜像)。

2. 将Redo日志处理下放到存储层

(1)Aurora架构

在这里插入图片描述
在替代EBS的位置,有6个数据的副本,位于3个AZ,每个AZ有2个副本。所以现在有了超级容错性。但是,为什么Aurora不是更慢了,之前Mirrored MySQL中才有4个副本。,这里通过网络传递的数据只有Log条目,这才是Aurora成功的关键。这是Aurora的第一个特点,只发送Log条目

这里的存储系统不再是通用(General-Purpose)存储,这是一个可以理解MySQL Log条目的存储系统。
EBS是一个非常通用的存储系统,它模拟了磁盘,只需要支持读写数据块。EBS不理解除了数据块以外的其他任何事物。而这里的存储系统理解使用它的数据库的Log。
所以这里,Aurora将通用的存储去掉了,取而代之的是一个应用定制的(Application-Specific)存储系统。

Aurora并不需要6个副本都确认了写入才能继续执行操作。相应的,只要Quorum形成了,也就是任意4个副本确认写入了,数据库就可以继续执行操作。所以这里的Quorum是Aurora使用的另一个聪明的方法。

(2)Aurora架构总结

传统数据库中:

  • 写操作不仅修改数据页,修改后同步产生redo日志项
  • 提交事务时,将redo日志刷屏成功才能返回

Aurora中:

  • 写操作只产生redo日志项
  • 存储层收到redo日志项,回放日志得到新数据页
  • 避免从头回放,存储层定期物化数据页版本

架构如下所示:
在这里插入图片描述

  • 三个AZ中,AZ1是主,其它AZ是从
  • (计算层)实例和存储层只传递redo日志和元数据
  • 写时主实例向6个存储节点发送redo日志,需要4个应答才认为日志持久化了
  • 回放日志可在后台运行,若读操作得到的是旧数据页,则会触发日志回放
  • 存储节点定期物化数据页,恢复时只需回放很少的日志,非常快速

(3)Aurora读写存储服务器

Aurora中的写请求并不是像一个经典的Quorum系统一样直接更新数据。对于Aurora来说,它的写请求从来不会覆盖任何数据,它的写请求只会在当前Log中追加条目(Append Entries)。所以,Aurora使用Quorum只是在数据库执行事务并发出新的Log记录时,确保Log记录至少出现在4个存储服务器上,之后才能提交事务。
这里的存储服务器并没有从数据库服务器获得到新的data page,它们得到的只是用来描述data page更新的Log条目。
但是存储服务器内存最终存储的还是数据库服务器磁盘中的page。
在存储服务器的内存中,会有自身磁盘中page的cache,例如page1(P1),page2(P2),这些page其实就是数据库服务器对应磁盘的page。
当一个新的写请求到达时,这个写请求只是一个Log条目,Log条目中的内容需要应用到相关的page中。可以等到数据库服务器或者恢复软件想要查看那个page时才执行。
存储服务器会在内存中缓存一个旧版本的page和一系列来自于数据库服务器有关修改这个page的Log条目。这里的Log列表从上次page更新过之后开始(相当于page是snapshot,snapshot后面再有一系列记录更新的Log)。
在这里插入图片描述
数据库服务器发出一个读请求。请求发送到存储服务器,会要求存储服务器返回当前最新的page数据。在这个时候,存储服务器才会将Log条目中的新数据更新到page,并将page写入到自己的磁盘中,之后再将更新了的page返回给数据库服务器。同时,存储服务器在自身cache中会删除page对应的Log列表,并更新cache中的page

数据库服务器写入的是Log条目,但是读取的是page。这也是与Quorum系统不一样的地方。Quorum系统通常读写的数据都是相同的。
数据库服务器执行了Quorum Write,但是却没有执行Quorum Read。因为它知道哪些存储服务器有最新的数据,然后可以直接从其中一个读取数据。这样的代价小得多,因为这里只读了一个副本,而不用读取Quorum数量的副本。(Log编号判断)

3. 存储服务设计的关键点

Aurora设计的关键原则是减少前台响应时间,所以尽可能将操作在后台异步执行,并根据压力自适应分配资源。
下面是一个写操作的具体流程:
①数据库实例(计算层)收到写请求,生成redo日志项,发送给存储节点,存储节点将日志项添加到内存队列中
②存储节点本地持久化redo日志项,并响应数据库实例
③整理日志,检查日志缺失
④和其它存储节点gossip,填补日志缺失
⑤回访redo日志,生成新数据页
⑥周期生成快照,备份数据页和日志到S3系统
⑦周期回收过期版本的数据页/快照
⑧周期对数据页进行校验
整个过程中,只有1和2是前台串行的(会影响延迟),其它都是后台操作。
在这里插入图片描述

五、日志延伸:一致性

本节介绍如何不用2PC提交协议下,如何生成redo日志,以保证持久化状态、运行时状态和副本状态的一致性。
具体如下:

  • 在崩溃恢复时,如何避免昂贵的回放开销
  • 解释常规操作,并解释如何维护运行时和副本的一致性
  • 提供恢复过程的具体细节

1. 异步日志处理

(1)首先介绍一些概念:

  • LSN(Log Sequence Number):每个redo日志全局唯一且单调递增的序列号
  • VCL(Volume Complete LSN):表示LSN在VCL之前,收到的日志在本存储节点是完整的
    故障恢复时,VCL之后的日志都要截断
  • CPLs(Consistency Point LSNs):事务可分成多个最小原子的mini-transaction(MTR),每个都有对应的最后一条日志LSN,这就是CPL;一个事务有多个CPL,所以叫做CPLs
  • VDL(Volume Durable LSN): 最大已持久化的LSN,满足
    ①VDL ≤ VCL
    ②VDL是CPLs中最大的一个
    从上面可知,日志完整性和日志持久化是不一样的。
    易知VDL表示了数据库处于持久化一致的位点,所以在故障恢复时:数据库以PG为单位,确认VDL,截断大于VDL的日志。
    (VCL之前日志完成,无空洞。CPL是微事务的结束点,即提交处。VDL是所有CPL中最大的一个,即最后一个微事务的结束点)
    (2)Aurora有多个只读数据库,这些数据库可以从后端存储服务器读取数据。所以,Figure 3中描述了,除了主数据库用来处理写请求,同时也有一组只读数据库。论文中宣称可以支持最多15个只读数据库。如果有大量的读请求,读请求可以分担到这些只读数据库上。
    当客户端向只读数据库发送读请求,只读数据库需要弄清楚它需要哪些data page来处理这个读请求,之后直接从存储服务器读取这些data page,并不需要主数据库的介入。
    在这里插入图片描述
    在这里插入图片描述

只读数据库也需要更新自身的缓存,所以,Aurora的主数据库也会将它的Log的拷贝发送给每一个只读数据库。这就是你从论文中Figure 3看到的蓝色矩形中间的那些横线。
主数据库会向这些只读数据库发送所有的Log条目,只读数据库用这些Log来更新它们缓存的page数据,进而获得数据库中最新的事务处理结果。
有一些问题:①我们不想要这个只读数据库看到未commit的事务。②数据库背后的B-Tree结构非常复杂,可能会定期触发rebalance。只有在rebalance结束了才可以从B-Tree读取数据。但是只读数据库直接从存储服务器读取数据库的page,它可能会看到在rebalance过程中的B-Tree。
这就涉及到了上面讨论的微事务(Mini-Transaction)和VDL/VCL
所以当一个只读数据库需要向存储服务器查看一个data page时,存储服务器会小心的,要么展示微事务之前的状态,要么展示微事务之后的状态,但是绝不会展示中间状态。

2. 标准操作

(1) 写

数据库实例向存储节点传递redo日志,收到足够的票数后,标记事务提交,VDL增加,从而进入新的一致状态。
不过由于系统并发执行很多事务,所以要避免VDL追不上LSN,有:

  • 定义并设置LAL,即LSN与VDL差值的上限,避免存储层成为瓶颈
    而由于底层存储是分片的,每个PG/每个分片只能见到部分日志,为保证PG/分片上日志的完整性,有:
  • 每条日志有当前PG前一条日志的指针
  • 定义SCL,表示LSN在SCL之前,收到的日志在本PG是完整的,存储节点通过gossip填补缺失的日志,以推进SCL

(2) 提交

提交是异步的:

  • 每个事务包含commit LSN,当VDL大于事务的commit LSN时,表示事务redo日志都已经持久化,则向客户端回复事务已成功执行
  • 处理回复是由单独线程执行的,因此整个提交流程不会阻塞

异步提交极大提高了系统的吞吐。

(3)读

读先从缓冲池获取,若缓冲池满才读盘,此时会挑选并淘汰数据页。
但是对于淘汰的数据页,Aurora直接丢弃,不会刷盘。所以需要保证被淘汰的数据页page LSN要不超过VDL,这就需要两个约束:

  • 数据页上的修改都已经持久化了
  • 缓存未命中时,通过数据页和VDL总能得到最新的数据页版本

对于读操作,正常情况下,不需要quorum:选定一个存储节点进行读取,它需要满足有最新VDL的数据。

(4)复制

写副本实例(主实例)可与至多15个读副本实例(从实例)共享一套分布式存储,因此增加读副本(从实例)不会消耗I/O资源,即零成本。
从上文可知,写副本会向读副本发送日志,读副本会回放日志,它需要满足,若不满足则忽略日志项:

  • 回放日志的LSN不超过VDL
  • 回放日志要以MTR为单位,确保副本能看到一致性视图

3. 故障恢复

(1)MySql的实现

因为Aurora使用的是与MySQL类似的机制实现,但在Mysql实现方式的基础上,进行了一些加速操作。
对于Aurora来说,最重要的是事务(Transaction)和故障可恢复(Crash Recovery)。
事务是通过对涉及到的每一份数据加锁来实现:
在这里插入图片描述
具体实现如下:
硬盘存储了数据的记录或以B-Tree方式构建的索引。所以有一些data page用来存放数据库的数据,每一个data page通常会存储大量的记录,而X和Y的记录是page中的一些bit位。
在硬盘中,除了有数据之外,还有一个预写式日志(Write-Ahead Log,简称为WAL)。预写式日志对于系统的容错性至关重要。
在服务器内部,有数据库软件DB,通常数据库会对最近从磁盘读取的page有缓存。
在这里插入图片描述
当你在执行一个事务内的各个操作时,例如执行 X=X+10 的操作时,数据库会从硬盘中读取持有X的记录,给数据加10。但是在事务提交之前,数据的修改还只在本地的缓存中,并没有写入到硬盘。提交之前我们还不想向硬盘写入数据,因为这样可能会暴露一个不完整的事务。
为了让数据库在故障恢复之后,还能够提供同样的数据,在允许数据库软件修改硬盘中真实的data page之前,数据库软件需要先在WAL中添加Log条目来描述事务。所以在提交事务之前,数据库需要先在WAL中写入完整的Log条目,来描述所有有关数据库的修改,并且这些Log是写入磁盘的。
在这里插入图片描述
a.第一条表明,作为事务的一部分,我要修改X,它的旧数据是500,我要将它改成510。
b.第二条表明,我要修改Y,它的旧数据是750,我要将它改成740。
c.第三条记录是一个Commit日志,表明事务的结束。
前两条Log记录会打上事务的ID作为标签,这样在故障恢复的时候,可以根据第三条commit日志找到对应的Log记录,进而知道哪些操作是已提交事务的,哪些是未完成事务的。
数据库写磁盘是一个lazy操作,它会对更新进行累积。当数据库重启时,恢复软件会扫描WAL日志,发现对应事务的Log,并发现事务的commit记录,那么恢复软件会将新的数值写入到磁盘中。这被称为redo,它会重新执行事务中的写操作。
(总结:硬盘中有操作日志的记录WAL,每一条有事务id通过是否有commit判断该事务是否提交。修改到磁盘前先写入WAL,实现故障可恢复事务。)

(2)总结

ARIES(Algorithm for Recovery and Isolation Exploiting Semantics,,这篇文章应该是WAL里面最有名的一篇了,发表在1992年,现在很多数据库WAL的设计上都有它的影子。

常规数据库采用基于ARIES协议进行故障恢复:

  • 周期性做checkpoint
  • 从上一个checkpoint回放redo日志
  • 根据undo日志回滚未提交的事务
    这需要检查点频率和故障恢复时间做权衡,但Aurora不需要。
    Aurora虽然也采用类似的方法,但是基于计算存储分离以及分片的设计:
  • 存储层部分失效时,能快速恢复
  • 数据库实例宕机后:①故障恢复只需要通过与存储节点read quorum,即可读到最新数据,并得到VDL以截断后面的日志。 ②由于LSN与VDL有差值限制,undo操作不会很多,且可在后台进行。

六、集成

整体在云上集成的架构如下所示:
在这里插入图片描述

  • 应用层:部署应用程序,与数据库实例交互
  • 数据库实例层:部署数据库实例(Aurora MySQL)
    ① 数据库实例包含一个主实例(读写)和多个从实例(只读),位于同一个物理区域,跨AZ部署
    ② 使用RDS管理元数据,每个数据库实例部署一个RDS HM,监控集群健康度,确定实例是否要切换或重建等
  • 存储层:部署存储节点
    ① 存储节点尾与同一物理区域,跨AZ部署(如至少跨3个AZ)
    ② 其中部分节点和S3相连,后台备份数据,必要时还原数据
    ③ 使用Amazon DynamoDB持久化存储配置、元数据信息、S3备份信息
    ④ 所有关键操作都会被监控,若性能和可用性不达标,则会触发警报

七、总结

本文的主要贡献点在于:

  • 重提“数据库即日志”的观念
  • 基于quorum机制,和下放redo日志处理,使用“计算和存储分离”的架构,减少I/O开销,提高吞吐,可用性增加,且能保证一致性
  • 提出分片存储,降低存储层恢复的时间,提高可用性
  • 大部分关键操作异步化、后台化,极大降低前台任务的延迟
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/622155
推荐阅读
相关标签
  

闽ICP备14008679号