赞
踩
在返校前的最后一周的计划是接着再看一篇论文,接着6.824课程推荐阅读的论文,这次是了Amazon Aurora:Design Considerations for High Throughput Cloud-Native Relational Databases。看论文加查资料,研究了两天,好吧,不得不说,对于我现有数据库的相关知识,这篇论文还是有些难的,只了解了个大概,很多细节方面还没搞懂,暂且先总结一部分,以后有机会在探索其细节部分。
如下图所示,为论文的整体布局(主要为前四个部分),下面总结主要从图示的几个部分入手。
Aurora 是一种由 AWS 于 2017 年提出的关系型数据库架构,它为 OLTP 业务提供关系型数据库服务。它将计算与存储分离、基于 Quorum 模型保证底层存储的一致性、将 redo 日志相关的功能下推到存储层、并通过读写分离降低数据库层的负载。
note:以上一段话虽然简单,但是基本概括了Aurora的精髓部分,每句话理解都需要对其所涉及的内容有相当程度的理解。
下面顺便稍微说下我传统数据库的架构方案:
DB 在处理事务的过程通常被视为一种分层的行为。系统在顶层对 SQL 语句进行解析,然后将得到的语法树传递给查询优化器层。查询优化器通过统计信息进行最优路径选择(CBO),这个阶段产生的物理执行计划与逻辑存储层交互,完成相应的操作。
一般来说,可以将事务处理引擎简化为两层模型:SQL 解析、SQL 执行以及优化视为查询处理引擎(Process Engine,PE);逻辑层存储和物理层存储统称存储引擎(Storage Engine,SE)。这对应 MySQL 可插拔存储的两层架构。如下图所示
Aurora中所说的讲计算与存储分离,应该讲的就是上图中的存储层和处理层分离。在Aurora中的基本架构如下图所示:
在这一部分,paper主要介绍了传统数据库架构的一些缺陷以及Aurora的一些设计优点。下面简要介绍:
对于云环境来说,传统的数据库架构有以下几个缺点:
(1)、网络IO已经取代CPU,硬盘等成为数据库性能提升的主要限制
(2)、数据库中有些操作很难并行,比如disk read 或者transaction commit。
而对于Aurora来说,其设计保持了以下优点:
(1)、通过独立出一个fault-tolerant 的存储层(storage tier),使得数据库系统可以在failure的时候性能不受太大影响。
(2)、通过限制数据库层(database tier,这里的database层包含传统数据库中的处理层,算是计算与存储分离中的计算层吧)向存储层只传递redo log信息,可以大幅度减少网络IO。
(3)、通过将backup以及redo recovery 转化为异步操作,可以提高crash recovery和backup的性能。
这一部分主要讲了三个方面的内容:
Aurora 利用Quorum这个 副本管理协议来抵抗关联失败(correlated failure)。(关于Quorum机制这里就不多说了,不了解的可以参照论文或者刘杰的《分布式系统原理介绍》Quorum一节。 )
Aurora被设计为能容忍:
(1)、挂掉一整个 AZ 以及一个额外的节点(AZ+1)而不影响读取数据
(2)、挂掉一整个 AZ 而不影响写入数据
根据上述设计,最终Aurora采用的N=6,W=4,R=3.
note:其实说实话,到现在我还并不是很了解什么是(correlated failure),这种failure在以前的论文中没出现过啊。因此,Aurora的设计规则虽然能看得懂,但是确实不知道是为什么。
Aurora 为了实现快速恢复,尽最大努力降低MTTR(Mean Time to Repair)。将存储数据分为10G为单位的 Segment。(Protection Group(PG)是一个逻辑单位,代表的是 6 个Segment)Segment 是维护与调度的最小单元,一个Segment 故障时,同 AZ 的万兆网络可以在 10 秒内就完成修复。
note:以上其实是数据分片的好处。我从知乎上截取了一下文字,更好的解释了数据分片的优点。
这里所讲的优势主要是利用segment 自动恢复的机制实现rolling update 。比如想要升级底层的操作系统和软件,可以直接把机器下线进行升级,上面的分片都会很快在别的机器上进行重建,然后再把机器加回集群升级下一个。发现某台机器硬件有异常也不需要做手工的数据迁移,直接把机器下线送修。另外当出现数据热点的时候也可以直接将这个热点机器的其他分片标记为不可用把分片迁移走,来避免某一个用户的行为造成其他用户的性能下降。这些都是分片带来的好处。
这一部分是Aurora的重点,主要讲了三个部分:
如上图所示,经典的MySQL主备系统有两个主要问题:
(1)、事务操作需要传输大量的数据,如redo log, double write, replicated blokc
(2)、不少操作是串行的,比如1,3,5,这会增加延时
上图的工作流程为:
(1)、主实例将 REDO 日志写入存储层。I/O 流根据目的地来将日志顺序打成 batch ,并将每个 batch 传给数据的6个副本并持久化到数据盘上
(2)、数据库引擎只要收到6个中的4个回复就形成了一个写多数派,此时可认为这些日志文件被持久化了
(3)、主实例将日志以及元数据的更新一起发送给副本实例
(4)、每个数据副本使用这些 REDO 日志将数据页的变更应用在他们的 buffer cache 中
(5)、对磁盘上数据库数据的写入(B-Trees等)可以在以后完成,通常是希望能够将多个事务对数据库同一部分的写入合并为一个磁盘写入。
基于此模型,实验表明,Aurora 可以负载比 MySQL 镜像多35倍的事务。
整个Aurora核心的一个设计要点就是:the log is the database。 所以在上面的架构中,Primary Instance (也就是database tier)只向存储层(storage tier)传送redo log,也就是上文说的将Redo Log下推到存储结点。每个存储节点根据 Redo log 来构成本地(Local Segment)存储状态,多个存储可靠性通过副本数来保障。每个存储节点也可以将Segment 定时同步到 S3 上增加可靠性。
note:注意以上的存储结点根据RedoLog 来构建本地的Segment 并不是像传统的log apply 一样:来一个redo log, 就将其变成 page data。 Aurora采取的是类似一种lazy page materialization机制,在空闲的时候或者apply 推迟到具体的read操作之时,这样通常是希望能够将多个事务对数据库同一部分的写入合并为一个磁盘写入。
在这个部分,paper描述了Aurora在降低延时方面的努力,就是通过将传统数据库中的一些同步操作变成异步操作,也就是将更多的操作放到后台执行。如下图所示。
其基本步骤如下:
(1)、接收日志记录并添加到内存中的队列
(2)、记录在磁盘上并进行 ack 返回
(3)、对于批量 Redo log 进行整理,确定没有批次丢失
(4)、与其它副本存储节点进行对齐(通过 Gossip 协议,它们可以知道集群中有哪些节点,以及这些节点的状态,每一条 Gossip 消息上都有一个版本号,节点可以对接收到的消息进行版本比对,确保二者得到的信息相同)
(5)、日志记录合并到新的数据页
(6)、定期将日志和新的页面复制到 S3
(7)、定期进行过期版本垃圾数据回收
(8)、定期验证 CRC 码页,如果发现损坏数据块,与相邻节点进行通信获取完好的数据块。这是 Aurora 实现可自主修复损坏数据块的关键技术
note:注意,只有步骤 1 和 2 完成,前台即完成(commit),其它操作都是异步进行。
这一部分涉及到Aurora的读写流程,论文中描述的不是很清晰,所以相对来说有些复杂。 这一部分,我还没怎么搞懂,尤其是涉及到众多的概念:LSN‘、VDL、SCL、 VCL… 给我搞的有种春天里细雨蒙蒙的感觉,暂且就没啥好总结的了。
具体的可以参照这篇博客
以后有机会在好好研究这部分内容吧。
好了,虽然这篇论文理解的不是很深刻,但还是体会到了一些东西。下面从一个高的层次来总结一下:
(1)、以前一个计算机大师曾经说过:大多数计算机方面的问题,都可以通过分层机制来解决。Aurora中将数据库的计算和存储分离就是一个很好地例子,通过将架构中一部分服务独立出来进行优化,或许能达到不错的效果。
(2)、同步和异步是一对相互的矛盾统一体。同步意味着合作,意味着等待;而异步意味着签署了合作协议,但是暂时不用等待。从某种程度上来说,如果能利用多线程机制把暂时不需要立即使用的东西进行Lazy处理,形成某种异步机制,或许能起到一定的优化效果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。