NineData 联合创始人周振兴(苏普)受邀参加2023年 ACMUG 第一站西安站,发表了《云数据库架构与选型》主题演讲。
ACMUG,全称为中国MySQL用户组 (All China MySQL User Group) ,是 MySQL 和 MariaDB 在中国最大的技术社区,是得到了 Oracle User Group Community、MairaDB Foundation、中国计算机行业协会开源数据库专业委员会等官方认可的社区组织,ACMUG 会邀请国内外顶尖互联网公司和大型企业技术专家,分享其在数据库、大数据、云原生、AIOps 等技术方向上的经验以及最新进展。
以下内容,根据周振兴在【2023年 ACMUG 第一站西安站 】线下演讲内容整理而成。
AWS 在 2009 年发布第一款云数据库产品 RDS MySQL,阿里云于2011年 也发布了自己的 RDS MySQL,到现在,云数据库技术已经经过了 14 年的发展。云数据库的架构已经变得非常复杂,上周则借着 ACMUG(中国 MySQL 用户组)的分享则总结了 AWS 和阿里云 RDS 的主要架构特点,并通过一张架构图汇总,帮助开发者根据需要在合适的场景选择合适的架构与规格。
该架构图包含了高可用架构、CPU 架构选择、存储类型选择等内容。该架构图不包括性能、精确的对应关系(如 SQL Server 支持的存储空间大小与 MySQL 有什么差别)等内容,暂时不包括 Aurora 架构(后续考虑补充)、Custom、Outpost 类型等。
AWS RDS 的高可用架构包括了单可用区(Single-AZ / Single DB instance)、多可用区(Multi-AZ DB instance)这两种常见类型,RDS MySQL/PostgreSQL 还提供了多可用区集群版(Multi-AZ DB Cluster)。
该选项清晰的描述了实例的在可用区级别的容灾能力:
这是 Amazon RDS 在去年发布新的架构形态,详细参考:AWS RDS 发布三节点形态,哪些业务场景应该选择?。该形态主要解决原来的“多可用区版本”备节点完全不可用(相对成本较高)的问题。
“多可用区集群版”使用了数据库的类似的半同步复制机制(参考系统参数判断出来的),数据库的事务写入需要至少两个(多数派)写入成功才成功,但因为有两个备节点,所以相比“多可用区版本”性能会更好,另外,因为是数据库层的复制,而不是块级别,写入和同步路径会更短,也会让延迟更低一些。
该版本,似乎是当前 Amaozn RDS 主推的版本(从 RDS 创建流程中的默认选项和选项顺序来看)。
当前,多可用区集群版是标准模板中的第一个、也是默认选项。
关于该版本的架构、优缺点等相关信息可以参考该文章获得更多详细内容:AWS RDS 发布三节点形态,哪些业务场景应该选择?
主流的云厂商都逐步开始提供 X86 和 ARM 架构的 CPU,AWS 在这方面是在这方面动作最早的。在2018年 re:Invent 上推出了第一代的 Graviton,2019年推出了 Graviton 2,2021年推出了 Graviton 3。可以认为,当前产品已经有一定的成熟度,根据 Percona 做的 MySQL 测试,我们也看到,Graviton 在不同的并发类型,都表现出了与 Intel X86 差不多的性能,并且在高并发(并发数超过 CPU 核心数量)时,Graviton 表现还要更好一些。
性能比较接近,成本又更低,所以,目前已经有不少客户在尝试通过 Graviton 实例降低成本。目前,AWS RDS 也有非常多的 Graviton 的规格供选择。
当前的建议是:可以考虑在部分业务中尝试使用 Graviton 降低成本,根据企业内部的负载情况,再逐步考虑扩大范围使用。
另外,值得一提的是,AWS RDS 提供的最大规格是 db.x2iedn.32xlarge,具备 128vCPU 4096GB,一般来说,企业内部绝绝大多数业务都是满足需要的。
接着来看看 AWS RDS 提供了哪些存储类型。
AWS RDS 当前主流的存储类型包括了 gp2、gp3、io1(预留 IOPS 的 SSD),以及一个已经过时的 HDD 存储。其中:
在实际的选择中,开发测试环境则可以使用 gp2 类型、一般业务使用 gp3 类型,对于核心业务则可以使用 io1 类型。
关于规格代码,国内的云厂商一般不是太强调,也不是太关注。但是 AWS 因为其规格代码非常规范,也非常简洁,所传达的含义也比较准确,所以很多时候,在提及规格时,大家会使用其规格代码,而不是使用 vcpu 数量和内存大小。
例如,db.m6gd.16xlarge,则可以知道这是一个数据库实例,64vCPU,256GB内存,并且为 Graviton 架构的第六代(Graviton 2)实例,并且在本地具备额外的 NVMe SSD。
可用区可以理解为一片机房区域。例如,在东京东部的某个机房区域,通常会有数栋机房。一个大区域(Region,例如东京)会有多个可用区。
一张图读懂阿里云数据库 RDS 架构与选型
在 v1 版本发布的时候,详细的介绍了阿里云数据库 RDS 主要架构类型、资源复用与规格、数据库专属集群、本地盘与云盘版、通用型与独享型、超配比等内容,这里不再赘述,如果感兴趣可以参考:一张图读懂阿里云数据库架构与选型。
数据库通常是企业业务架构中的核心组件,数据库的可用性与业务可用性直接相关。所以,高可用是云数据库架构选型第一个需要关注的内容。
从高可用角度,阿里云数据库提供了基础版(即单节点)、双节点高可用版、三节点企业版。不同的版本,则是在成本、可用性、数据可靠性之间的平衡:
阿里云基础版使用阿里云云盘作为数据库存储,挂载在数据库的计算节点上,实现了存储与计算的分离。这使得,计算节点出现故障的时候,重新使用一个新的计算节点,再重新挂载原来的数据库存储,即可启动数据库,恢复出现故障的数据库。所以,在计算节点发生故障的时候,RPO 通常小于1分钟,RTO 则为5分钟~一小时。当整个可用区发生故障的时候,RPO 和 RTO 的值则依赖数据库备份的频率情况。
两节点高可用是用户使用最多的版本,也是数据库最为常见的架构。数据库由主备两个节点组成,通过数据库层的逻辑日志进行复制。相比单节点,无论是在数据可靠性、服务的可用性都有非常大的提升。由于主备节点都在同一个大 region,日志延迟通常都非常小,所以发生单节点故障时,高可用版的数据可靠性通常是比较高的。注意到,AWS 对应的双节点版本的 RPO 是零,那么阿里云数据库怎样呢?
具体的,对阿里云 RDS MySQL,阿里云的两节点高可用,根据所选择的参数模板分为如下三类:
其中,“高性能”版本和“异步”版本,都是异步复制,在发生主节点故障时,因为复制为异步的,可能会有少部分的事务日志没有传到备节点,则可能会丢失少部分事务。也就是说,这两个版本为了实现更好的性能,在数据库的 RPO 上做了小的让步。“默认”版本,使用了半同步复制,通常,数据可靠性会更高。但因为半同步可能会有退化的场景,所以,该模式下数据复制还是在极端的情况下,还会有数据丢失的可能性。
那么,既然“异步”模式和“高性能”都有数据丢失的风险,他们的区别是什么什么呢?简单的概括,“异步”产生微小数据丢失的可能性更小。因为,主备节点通过设置sync_binlog=1,
innodb_flush_log_at_trx_commit=1,可以最大可能性的保障,主节点的数据可靠性。
事实上,高可用版本是可以满足绝大多数业务场景的需要的,一方面同一个可用区内数据传输延迟非常小,日志传输通常都非常通畅,即便主节点发生故障,实际的情况中,通常不会出现日志延迟。另外,主节点失败后,通常可以通过重启等方式恢复,云厂商的硬件都有着较为标准的硬件过保淘汰的机制,硬件完全不可用的情况也并不多。另外,底层磁盘会通过硬 RAID 或者软 RAID 的方式,保障磁盘数据存储的可靠性,数据即便是在一台机器上,也会保存在两块盘上。
两节点高可用版本在某些特殊场景下,数据还是存在一些不可用风险,例如,当其中一个节点发生故障,而本地数据量又非常大时,需要重新在一台新的机器上搭建备节点时,因为数据量较大,重建时间通常会比较长,而这时候,主节点则会一直单节点运行,如果不幸主节点再出现故障,则会出现不可用或者数据丢失。如果,对数据的安全性有更高的要求,则可以考虑选择“三节点企业版”。
当前仅 RDS MySQL 有该版本。三节点企业版使用了基于 X-Paxos[^4] 的一致性协议实现了数据的同步复制,适用于数据安全可靠性要求非常高的场景,例如金融交易数据等。三节点中,有一个节点仅存储日志,以此实现接近于两个节点的成本与价格,实现更高的数据安全与可靠性。
三节点企业版在创建的时候,可以选择分布在1~3个可用区。如果需要跨可用区的容灾,则可以让三个副本分布于三个可用区,如果需要更高的性能,则可以让三个副本都在同一个可用区。
在阿里云 RDS 的高可用参数模板选择中,不同的参数模板,最主要的区别就是这两个参数的不同配置。这是 MySQL 和 InnoDB 在数据安全性上最重要的两个参数。双1设置(sync_binlog=1,
innodb_flush_log_at_trx_commit=1)是数据安全性最高的配置。
数据库是日志先行(WAL)的系统,通过事务日志的持久化存储来保障数据的持久化。在一般的 Linux 系统中,数据写入磁盘的持久化需要通过系统调用 fsync 来完成,相对于内存操作,fsync 需要将数据写入磁盘,这是一个非常“耗时”的操作。而上面这两个参数就是控制 MySQL 的二进制日志和 InnoDB 的日志何时调用 fsync 完成数据的持久化。所以,这两个参数的配置很大程度上反映了 MySQL 在性能与安全性方面的平衡。
其中,sync_binlog 代表了,MySQL 层的日志(即二进制日志)的刷写磁盘的频率,如果设置成 1,则代表每个二进制日志写入文件后,都会进行强制刷盘。如果设置成 0,则代表 MySQL 自己不会强制要求操作系统将缓存刷入磁盘,而由操作系统自己来控制这个行为。如果设置成其他的数字 N,则代表完成N个二进制日志写入后,则进行一次刷写数据的系统调用。
innodb_flush_log_at_trx_commit 则控制了 InnoDB 的日志刷写磁盘的频率。取值可以是 0,1,2。
我们可以通过下图来理解这两个参数的含义,以及在操作系统中对应的“写入文件系统”与“刷写数据到磁盘”的含义。首先,在数据库的事务处理过程中,会产生 binlog 日志和 InnoDB 的 redo 日志,这两个日志分别在 MySQL Server 层面和 InnoDB 引擎层面保障了事务的持久性。在事务提交的时候,数据库会先将数据“写入文件系统”,通常文件系统会先将数据写入文件缓存中,该缓存是在内存中,这样就意味着,如果发生操作系统级别的宕机,那么写入的日志就会丢失。为了避免这种数据丢失,数据库接着会通过系统调用,“刷写数据到磁盘”中。此时,即可以认为数据已经持久化到磁盘中。
这时,再回头看看阿里云 RDS 的参数模板。在高性能模板中,”sync_binlog=1000,
innodb_flush_log_at_trx_commit=2, async”,代表了在写入1000个 binlog 日志后再进行刷写数据到磁盘的操作,InnoDB 的日志则都会先写入文件系统,然后每隔一秒进行一次刷写数据到磁盘。在“默认模式下,“默认:sync_binlog=1, innodb_flush_log_at_trx_commit=1, semi-sync”,则是最严格的日志模式,也就是会保障每个事务日志安全的刷写到磁盘。
日志的刷写模式对性能有非常大的影响。如果不去关注这些参数,就直接去测试不同云厂商的性能,则会发现,云厂商之间的 RDS 有着非常大的性能差异。通常,这些差异并不是厂商之前的技术能力导致的,更多的是由于他们在对于安全性和性能的平衡时,选择的不同的平衡点。
从资源共享与隔离上,RDS 又分为:通用型、独享型和共享型。具体的:
除了,上述主要规格类型之外,阿里云还提供了“独占物理机”规格,选择该规格的用户可以完全的独占一台物理机的资源:
专属集群 MyBase 是阿里云推出的一种特殊的形态。可以理解为,是一种全托管 RDS 与自建数据库的中间形态。在全托管的 RDS 基础上,提供了两个重大的能力:
当然,要求是用户一次购买一个非常大的、可以容纳多个 RDS 实例的“大集群”,专属集群则提供了以上两个能力,以及 RDS 其他的基本能力,包括安装配置、监控管理、备份恢复等一系列生命周期管理能力。
使用这种规格,用户具备更大的自由度。一方面可以登录主机,观测主机与数据库的状态,或者将自己原有的监控体系部署到专属集群中。另一方面,用户可以根据自己的业务特点,控制集群内的 CPU 资源的超配比。对于核心的应用,则使用资源完全不超配的集群;对于响应时间没有那么敏感的应用,例如开发测试环境,则可以配置高达 300% 的 CPU 超配比,以此大大降低数据库的成本。
阿里云的主要版本都会支持本地 SSD 和高性能云盘。他们的差异在于计算节点与磁盘存储是否在同一台物理机器上,对于使用高性能云盘的规格,通常是通过挂载一个同地区的网络块设备作为存储。
对于阿里云厂商来说,未来主推的将是云盘版。原因是云盘相对于本地盘来说,有很多的优势:
当然,使用云盘也有一些缺点,例如,相比本地盘,云盘的访问延迟更大,需要通过网络访问,而对于数据库这类 IO 极其敏感的应用,本地磁盘的 IO 性能的稳定性通常会更强一些。
独享型规格的资源完全由用户独立使用,价格通常更贵。而通用型则因为部分资源的共享,会导致性能在某些不可预期的情况下发生一些不可预期的波动。而独享型规格也更贵,更多的企业级场景,也会推荐使用独享型,会有很多人会认为独享型的性能也更高。而实际上,如果做过实际测试就会发现,一般来说,相同的规格,通用型的性能与吞吐通常都会更高。
所以,实际情况是,通用型的价格更加便宜,性能也会更好。缺点在于,可能会出现一些不可预期的性能波动,而因为大多数数据库应用都是 IO 密集型的,所以,实际场景中,这种不可预期的波动并不是非常多。
所以,这两个版本的选择,需要用户根据自己的实际情况去选择。如果,可以接受偶尔的性能波动,则一定是建议选择通用型的;如果应用对数据库的响应时间极其敏感,则应该选择独享型。另外,当前,通用型最大规格仅支持 12核 CPU,所以对于压力非常大系统,则只能选择独享型。
对于在线数据库应用来说,通常是 IO 或者吞吐密集型的。CPU 资源在很多时候,会有一定的冗余。对于云厂商来说,则可以通过超配 CPU 的售卖率来降低成本,同时也降低数据库资源的价格,这就是通用型背后重要的逻辑。
而一般来说,可以超配的通常只有 CPU 资源。磁盘资源虽然可以超配,但是实际使用中,是不能重合的,当用户的磁盘占用增到购买值的时候,资源则不可以共享,这与 CPU 的超配并不相同。内存资源则更加是独享的,Buffer Pool 的通常是满的,无论这些内存页是否被实际使用,数据库总是会尽力在内存中存储尽可能多的数据。
MyBase 提供的一个重要配置项,就是可以由用户自定义底层资源的超配比,该比率取值从100%~300%。也就是说,一个 32核 CPU 的资源,最多可以分配给12个8核 CPU 的实例使用,看起来是96=12*8个 CPU 被使用,即实现了 300% 的超配比。
超配比,有时候也会被称为超卖率。
阿里云数据库在去年11月宣布推出基于 ARM 架构的 RDS 实例,可以向用户提供更高性价比。根据 ARM 芯片的定位,一般性价比更高,但是性能上限相比于 x86 的芯片要差一些。所以,如果数据库实例压力不是很大,而又考虑成本降低,则可以考虑尝试 ARM 架构的 RDS。
另外,zhoujy 在去年11月份对该实例进行测试,相关的数据库可以参考:MySQL该用哪种CPU架构服务器。
当前,基于 ARM 的 RDS 实例上线时间还不是很长,如果是生产环境的话,建议做较为全面的测试后再上线。
在2022年底,阿里云 RDS MySQL 发布了集群版。该产品形态类似于 AWS 提供的“Multi-AZ Cluster”,场景也比较类似。对比最常用的双节点高可用版本,该”集群版”将其备库的连接地址提供了出来,直接可以用于用户业务,帮助用户降低使用成本。另外,也可以考虑将主库的部分流量直接迁移到备节点,降低主库压力,提升主库的可用性。
如果,在业务场景中,使用了1~2个只读实例的,则可以考虑直接使用该集群版本来代替原有的只读实例。成本可以得到非常大的降低。
RDS Serverless 是一种优于按量付费、包年包月的资源使用的模式。它提供了自动化的弹性扩缩容,用户无需提前选定规格,后端会根据系统压力进行自动升降配,并根据实际使用计费,当然,用户可以设置 Serverless 实例的最大和最小规格,限制资源最大使用量和最低的服务能力。
对于峰谷明显的业务系统,该模式一方面可以在需要时提供很高的资源规格应对压力,另一方面可以在低峰时降低资源使用量,最终降低成本。
也注意到,最近阿里云数据库也介绍了客户“微财”使用 Serverless 实例构建云上灾备的案例。使用 Serverless 构建云端低成本的灾备,确实是一个非常好的场景,一方面满足了客户底层本的诉求,另一方面客户本地的实例如果真的出问题,依旧可以非常快速的接管。
关于更多 Serverless 测试可以参考:实测阿里云 RDS Serverless。
AWS 和阿里的数据库产品各自都发展了很长时间,所处的市场环境、客户场景都有很大的不同,所以,其产品形态也有很多不同的地方,即便是看似相同的名称其含义也可能不同。这里整理,阿里云和 AWS RDS 产品的一些差异,以便帮助大家更好的选择产品:
无论是在阿里云还是 AWS,这两个版本都是代表了单节点的架构。但是:
这两个版本都是各自厂商的主流版本,是符合大部分 OLTP 业务场景的。但两个厂商的实现各有一些不同,阿里云使用的是数据库层的逻辑复制,AWS 使用了 EBS 层的同步物理复制。阿里云 RDS MySQL 在数据保护上,则提供了“高性能”、“异步模式”、“默认”等参数模板,可以让用户在数据保护和性能之间进行一定平衡和选择,而 AWS RDS 则使用了 EBS 的同步物理复制,最大限度的保护事务安全。
阿里云 RDS 的 ARM 规格上线时间比较短,如果要考虑在生产环境使用,还是建议做较为充分的业务测试。相比,AWS Graviton 实例已经上线有3年时间,也有很多的使用案例,相对要更加的稳定。另外,AWS Graviton 实例在性价比上确实更加明显,这一点,无论是第三方的测试还是官方公布的一些数据,都得到了证实。所以,如果部分业务,考虑降低成本,则可以尝试使用 AWS Graviton 实例。
ESSD 的性能上限是更高的,目前 ESSD PL-X 类型已经声称提供了300万的 IOPS 能力。AWS RDS 所使用的 io1 最大 IOPS 则是25.6万。一直以来,AWS RDS 被诟病比较多的是其按照 IOPS 计费的复杂逻辑,虽然,看似产品细节非常细致,但是实际让用户选择和使用的时候很困惑,另一面,阿里云和其他云厂商都以存储空间计费,更加简单,并提供与存储空间大小为一定比率的 IOPS 能力。
AWS 存储的一个优点是,其提供了非常明确的 IOPS SLA,io1 规格,其 SLA 是99.9%的 IO 请求响应时间是毫秒级,这反应了 AWS 可以向用户提供非常稳定的 IOPS,而不是仅仅简单的最求 IOPS 上限。
AWS 在小规格的版本提供了突发性能型实例,可以提供一定的 CPU “超用”(购买了 2v CPU,实际使用更多 v CPU)能力,同时,其“超用”和限制的规则都非常明确。
阿里云则为了更好的性价比,则向用户提供了“共享型”、“通用型”、“独享型”,让用户在性能稳定性牺牲非常非常小的情况下,获得更高性价比的实例规格。另外,阿里云提供的 MyBase 规格,更可以自己定义“超卖”比率,让用户根据自己的业务类型和特点进行自定义的配置。阿里云的“独享型”资源则全部由用户独立使用,也可以保障非常好的性能稳定性。
AWS 的规格代码非常简洁、准确,含义清晰,并且有非常好的连续性。从规格代码中很容易了解到该规格的特点、大小等特性。
阿里云和 AWS 两家的云厂商的数据库服务都经过了十来年的发展,他们在各自的市场和场景下,都非常好的满足了他们客户的诉求,本文档旨在帮助大家能够从整体框架加上了解两家厂商主要数据库产品 RDS 的架构。所以在介绍中省略了非常多的细节内容,也牺牲了一定的精确性,这些内容可以参考各种厂商的文档,这里不做赘述。
周振兴(苏普),NineData.cloud 联合创始人,Oracle ACE(MySQL方向),数据库领域畅销书《高性能MySQL》第三、四版的译者,曾任阿里云数据库资深专家。