Amazon Aurora介绍
Amazon Aurora是AWS提供的一种关系数据库服务,旨在提供高性能、高可用性和经济高效的数据库解决方案。提供完全开源的 MySQL 兼容版和 PostgreSQL 兼容版,以及一系列用于构建无服务器和机器学习(ML)驱动型应用程序的开发工具。它基于PostgreSQL和MySQL,但提供了更好的性能和可扩展性。Amazon Aurora的设计目标是提供比传统数据库更快的查询性能,同时保持与MySQL和PostgreSQL的兼容性,使得用户可以轻松迁移现有应用程序到Aurora上。
Aurora 采用一种有容错能力并且可以自我修复的分布式存储系统,这一系统与计算资源分离并可以把每个数据库实例自动扩展到最高 128 TiB。它具备高性能和高可用性,支持最多 15 个低延迟只读副本、时间点恢复、持续备份到 Amazon Simple Storage Service (Amazon S3),还支持跨三个可用区(AZ)复制。
Aurora 也是一项完全托管式服务,该服务使耗时的管理任务(例如硬件调配、数据库设置、修补和备份)自动化,同时以 1/10 的成本提供商用数据库的安全性、可用性和可靠性
Amazon Aurora的主要特点包括:
- 高可用性和持久性:Aurora提供了99.9999%的持久性,确保数据的安全性和可靠性。它支持自动备份和恢复功能,以及故障自动切换,以保障服务的连续性。
- 性能优化:Aurora通过使用高性能的存储层和并行处理技术,显著提高了查询性能。它能够处理大量并发读写操作,满足高负载的工作场景。
- 经济高效:Amazon Aurora提供了按使用量计费的模型,用户只需为实际使用的资源付费。此外,AWS Free Tier还提供了一定的免费数据传出额度,进一步降低了成本。
- 易于管理和扩展:Aurora的管理和控制台使得数据库的管理和维护变得简单。用户可以根据需要轻松地扩展数据库的容量,以满足不断增长的数据和用户需求。
- 兼容性和可迁移性:Aurora与MySQL和PostgreSQL兼容,使得从传统数据库迁移到Aurora变得相对容易。这有助于减少迁移过程中的技术障碍,加速现代化进程。
Amazon Aurora提供了两种配置选项:
- Aurora Standard:这是一种经济实惠的数据库集群配置,适用于大多数I/O使用率较低到中等的应用程序。
- Aurora I/O-Optimized:这是一种专为I/O密集型应用程序设计的配置,如果I/O支出超过总支出的25%,使用Aurora I/O-Optimized可以节省多达40%的成本。它为所有应用程序提供可预测的定价,因为读取和写入I/O操作不收取任何费用。
Aurora架构
Aurora是亚马逊云服务(Amazon Web Services,AWS)推出的云原生数据库服务,在MySQL 的基础上实现了存储计算分离架构,主要面向联机事务处理(On-Line Transaction Processing,OLTP)场景,Aurora 的整体架构如下 所示。
当我们创建一个Aurora实例时,我们先创建一个数据库集群。数据库集群由一个主实例和一个集群卷组成。此外,我们还可以创建一个Aurora副本集。它可以进行连续备份到AWS S3(简单存储服务),并对数据以保持99.999999999%的耐久性。
Aurora从分配给实例80GB的块开始,并分配10GB的块作为自动缩放的一部分。
主实例
- 支持读/写工作负载
- 对集群卷执行所有数据修改
集群卷
- SSD虚拟数据库存储卷
- 支持多个可用区域(AZ)
- 每个AZ都有两个集群数据副本
- 由主实例和Aurora副本共享
Aurora副本集
- 支持只读操作
- 最大副本数可以是15
- 多个Aurora副本,以支持读取工作负载的分发
- 多个Aurora副本意味着增加数据库可用性
- 如果主实例失败,其中一个Aurora副本将被提升为主实例
下面我们来看一下Aurora架构图:
Aurora是一个基于SOA的实现,它分为几层:存储层、日志层、缓存层,这些都是作为单独的层,而SQL和事务已保存在单个层中。这种架构实现了更多的可扩展性、高可用性和性能。
创建Aurora实例
登录到AWS管理控制台并导航到Amazon RDS部分,就可以创建Aurora集群。
首先选择数据库、主实例的大小、数据库凭证、数据库名称、端口号等。
然后,选择“Launch DB Instance”以启动Aurora实例。在“Instances”选项卡下,可以看到新创建的实例,其中有可用于从应用程序连接的端点和端口号
Aurora性能
Amazon Aurora是亚马逊云科技自研的云原生关系数据库,它在提供和开源数据库MySQL、PostgreSQL的完好兼容性同时,也能够提供和商业数据库媲美的性能和可用性。
Aurora的性能提升不仅包含应用读写吞吐量的提升,也包含复制延迟的降低。一个Aurora集群包含1个写节点和多达15个读节点。在写节点和读节点之间的数据传输机制上,Aurora创新性地使用Redo Log传输来实现。Aurora的架构是计算存储分离,写和读节点共享存储,在写节点处理写请求时,会将Redo Log传送给存储系统,同时也会传送给读节点。读节点在收到Redo Log后,会判断Redo Log所修改的数据页是否在自己当前的缓冲区中:如果存在,可以按照一定逻辑将Redo Log应用到对应数据页上;如果不存在,可以直接忽略掉这部分Redo Log,后续需要时可以直接去共享存储中读取数据页。Redo Log的传输使得数据传输量相比传统的Binlog大幅降低,再加上读节点应用Redo Log的简洁处理逻辑,使得Aurora的复制延迟很低,通常在20毫秒以内。相应处理逻辑如下图所示。
由于低复制延迟和读节点自动伸缩的能力,用户可以将非必须要求强一致的应用分散部署到Aurora不同节点上。高性能、高可用以及良好的扩展性使得Aurora得到用户的喜爱,也一度成为亚马逊云科技用户使用量增幅最快的服务。
因为Aurora本身读写节点是通过Redo Log复制的,如果单纯使用Aurora,是不需要开启Binlog的。但是,用户有时也需要把数据从OLTP数据库中导出,比如去做后续的复杂数据分析等。对于MySQL而言,数据导出最通用的方式便是Binlog。Aurora MySQL与社区MySQL是完好兼容的,所以也支持消费端以Binlog Consumer的方式来将数据持续导出。打开Binlog以及有Binlog Consumer连接都会对MySQL带来性能上的影响,所以Aurora MySQL在Binlog方面不停进行优化,力争减少开启Binlog带来的影响。
本篇聚焦Aurora MySQL在Binlog方面的优化历程,首先会介绍下Binlog的机制,然后会分享下Aurora MySQL的Yield机制和Binlog I/O Cache,最后会重点介绍下Aurora MySQL 3推出的Enhanced Binlog这一新功能以及对应的性能测试情况。
Binlog机制
Binlog是MySQL主从节点同步数据的最常见方式。在主节点开启Binlog后,MySQL会在事务执行过程中记录数据页变更Redo Log的同时,也会记录Binlog,来描述数据在逻辑意义上的修改。Binlog最小的单位为Binlog Event,多个Binlog Event构成一个Binlog文件,一个Binlog文件的大小通常是128MB。对于大事务,Binlog文件大小也可能会超过128MB。Binlog有Row、Statement和Mixed三种不同的格式,可以决定Binlog Event中数据存放的内容,Row表示真实的数据,Statement表示SQL语句,而Mixed是两者的混合,会尽可能采用Statement格式来记录Binlog,在Statement方式在某些场景下可能导致主从不一致的情况下(比如获取当前系统时间),会采用ROW格式来记录Binlog。开启Binlog本身会需要额外的数据处理和刷盘逻辑,会带来一定的性能损。
当有另一个模块需要消费Binlog时,它会以Binlog Consumer的身份连接到主节点。下图展示了另一个MySQL数据库作为Binlog Consumer的情况下主从同步机制的示意图。实际应用中也有可能会是其他流数据处理工具比如Kafka、DMS连接到MySQL主库,MySQL主库的处理逻辑都是相同的。
每当有一个副本连接到MySQL主库时,MySQL主库中都会有一个Dump线程专门用来读取Binlog Event,并将Binlog Event通过网络发送给Consumer。如果Binlog Consumer也是MySQL数据库,会有一个专门的IO线程来接收主库传输的数据,并将接收到的Binlog Event存放在Relay Log中。从库MySQL上还会有一个或者多个SQL线程,来读取Relay Log,并将读取到的Binlog Event进行重放,从而使从库得到与主库一致的数据。
主库上因为前端线程在处理用户写入请求时需要将Binlog Event写入到Binlog文件,而Dump线程需要读取Binlog文件,尽管Binlog文件通常以128MB为单位进行存储,当两者操作同一个Binlog文件时,仍然会带来加锁竞争等,所以有Binlog Consumer连接到MySQL主库时会进一步由于锁冲突额外消耗MySQL主库的资源,影响到前端应用程序的返回时延。MySQL支持多个Binlog Consumer同时连接,但每个连接都会有对应的Dump线程来读取Binlog,连接数越多,对主库的性能影响也就越大。
Aurora MySQL的Yield和I/O Cache机制
Aurora MySQL兼容社区版MySQL,在Binlog处理逻辑上尤其是前端线程、Dump线程、IO线程和SQL线程等处理上与社区保持一致,只是将Binlog文件的存储由本地磁盘转到了远程的共享存储上。所以开启Binlog以及有Binlog Consumer连接到Aurora MySQL同样会带来性能的损耗。
Aurora MySQL一直致力于减少由于开启Binlog对Aurora带来的性能影响。在Aurora MySQL 1.17.6和2.04.5版本中提出了Binlog Yield的机制,Aurora MySQL 2.10版本中进一步提出了I/O Cache的机制来减少Binlog竞争冲突。
Binlog Yield的含义是在Dump线程与前端应用对应的线程在操作同一个Binlog文件引发冲突时,让Dump线程Yield等待一段时间,等到等待时间期满或者前端应用线程操作完毕当前Binlog文件,再让Dump线程继续工作。等待时间由变量aurora_binlog_replication_max_yield_seconds控制。Yield的机制能够在发生冲突时优先执行前端应用线程,能够降低对用户应用的响应延迟,但会一定程度上会带来复制延迟的增加。
Binlog I/O Cache顾名思义是单独开辟一块内存缓冲区,用来存放Binlog。前端线程可以将Binlog Event写入到内存缓冲区中,Dump线程可以从内存缓冲区中读取Binlog。在Binlog复制延迟比较低的时候,Dump线程和前端线程的交互可以在内存中完成,而不再需要去远程存储系统中读取并加锁处理,因此提升了Binlog复制传输的性能。
Aurora MySQL 3的Enhanced Binlog
Aurora MySQL 3.03支持的Enhanced Binlog从另一个角度降低了开启Binlog带来的性能损耗。它能将打开binlog对应用程序的影响降低到13%(之前可能最高达到50%),也能提升计算节点的吞吐。此外,Binlog开启时,数据库故障恢复效率与社区版binlog相比提升了99%。
上面示意图对比展示了Enhanced Binlog和普通Binlog在Aurora MySQL架构中的不同。Enhanced Binlog提出以前,如果用户把Aurora MySQL引擎开启了Binlog,Aurora MySQL写节点在写Redo Log的同时,也会把Binlog写出到存储中去,这样,在发生写节点failover时,新的写节点就能依据共享存储中的信息做好failover以及后续持续写入。另外,Binlog文件的写入是串行完成的。在Enhanced Binlog架构图中,Aurora MySQL将Binlog存储在单独的存储引擎中,并更改了计算层和Binlog引擎中交互Binlog的方式,从串行写封装文件接口的形式改成打散并行写Binlog Event的形式,Binlog引擎可以完成Binlog Event的排序和归集。
上图进一步展示了Aurora MySQL开启Enhanced Binlog之前和之后对应的处理逻辑的对比。传统Binlog处理流程是两阶段提交的方式,即Redo Log Prepare->Binlog Commit->Redo Log Commit。Binlog刷盘的动作是在Redo Log Prepare完毕顺序刷到存储层,128MB的Binlog文件刷出是需要经历一段时间的,对于较大的事务,Binlog文件也可能超过128MB。当然,Aurora MySQL 2也对超过512MB的大Binlog文件做了提前拷贝到存储层的优化,但对于512MB以下的Binlog文件,传输时需要耗费一定时间的。而Enhanced Binlog单独的存储引擎存放Binlog,可以使得刷Redo Log和Binlog的操作可以同步进行,在事务提交时,直接就通知两个存储引擎进行单独的Commit操作,节省了等待Binlog刷盘的时间。
Enhanced Binlog测评
针对Aurora MySQL Enhanced Binlog,也做了一些测试。现有两套Aurora MySQL集群:
- Aurora MySQL 3.03.1版本。R6g.8xlarge集群,一写一读,打开Binlog。
- Aurora MySQL 3.03.1版本。R6g.8xlarge集群,一写一读,打开Binlog,并打开Enhanced Binlog。
为打开Binlog,设置参数binlog_format为ROW。为了使用Sysbench测试较高并发,将max_prepared_stmt_count设置成了最大值1048576。
为打开Enhanced Binlog,设置了三个参数aurora_enhanced_binlog,binlog_backup,binlog_replication_globaldb,参数取值如下图所示。
运行的负载是采用Sysbench进行压测,Sysbench运行在EC2上,EC2机型是c5.18xlarge。测试过程中EC2没有成为瓶颈。
测试了两组不同的数据:1)16张表,每张表1千万条记录;2)250张表,每张表25000条记录。测试的Sysbench并发请求从2,4,8,一直增加到4096。
下面展示了16张表每表1千万条记录的测试结果。可以看到随着并发线程的增多,Enhanced Binlog的优势愈发明显,在4096个并发线程时,Enhanced Binlog能达到41%的性能提升。
下面展示了250张表每表25000条记录的测试结果。可以看到和前面类似的结论。随着并发线程的增多,Enhanced Binlog的优势愈发明显,在4096个并发线程时,Enhanced Binlog能达到23%的性能提升。
下面表格展示了Enhanced Binlog故障恢复的速度。可以看到Enhanced Binlog能够将故障恢复的速度提升92%以上。
此外,还针对ZeroETL进行了测试,因为ZeroETL是依赖于Aurora Enhanced Binlog的,测试结果表明,即便开启了ZeroETL,即有Binlog Consumer从Aurora MySQL中读取数据,Aurora MySQL对OLTP的性能保持不变。原因在于ZeroETL能够从Binlog存储引擎中直接读取数据,无需再联系Aurora MySQL计算节点。
总体而言,单独的Binlog存储引擎有几个优势:
- 提升性能:存储层进行Binlog排序逻辑,可以增加计算层的并行度,减少加锁,加速事务两阶段提交的速度。
- 加速故障恢复:避免传统Binlog故障恢复时必须顺序读取Binlog到计算层的操作。可以在保证一致性前提下按需恢复事务。可以将故障恢复时间从几分钟降低到几秒。
- 是实现直接从Aurora MySQL存储层取Binlog的基础。比如Aurora MySQL和Redshift之间的ZeroETL功能就是基于Enhanced Binlog来执行实现的,避免了有Binlog Consumer连接到Aurora MySQL计算实例对于计算节点资源的进一步竞争和消耗。
Aurora 动手实验&对比RDS Mysql性能
实验包括:
创建一个Aurora实例
使用MySQL Workbench连接Aurora和RDS MySQL
通过dump file 加载数据到Aurora和RDS MySQL
使用查询语句验证Aurora和RDS MySQL性能
Task1:创建Aurora数据库:
创建一个Aurora数据库,跟创建RDS一样,登录AWS管理控制台,搜索Aurora,创建数据库。
数据库类型选择,Aurora with MySQL compatibility,其他默认就好。
Templates选择 Dev/Test
DB instance size 选择db.t3.small就好,因为是测试环境,如果是生产环境选择Memory Optimized的类型R系列。土豪在测试时选择高配实例也可以。
注意在security group放行的端口,由于测试环境,我们可以都放行。
其他配置保持默认即可,创建数据库。
然后创建一个同类型的(db.t3.smal)RDS mysql数据库。
创建成功后如下:
Task2:连接跳板机并安装MySQL workbench:
跳板机为windows 或 Linux 都可以,我这里以windows 举例:
Task3:通过跳板机连接Aurora和RDS MySQL
Aurora endpoint:
Mysql endpoint:
登录跳板机,连接Aurora
Task4:导入SQL Dump文件到数据库中。
不熟悉SQL dump的同学,这个文件大概就是下图的样子,很好理解,定义Schema,然后插入数据。
运行Powershell,下载dump file到桌面
Invoke-WebRequest https://s3-us-west-2.amazonaws.com/aws-tc-largeobjects/SPLs/sharedDatabases/world.sql -OutFile c:\Users\Administrator\Desktop\world.sql
导入数据:
同样,Mysql再做一遍。不赘述了。
Task5:执行查询:
Aurora执行结果: