论文地址: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就是数据库。
好处:
- 提高了整体服务的吞吐(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整体架构