优化 AWS Aurora 实例的写入性能

Posted

技术标签:

【中文标题】优化 AWS Aurora 实例的写入性能【英文标题】:Optimize write performance for AWS Aurora instance 【发布时间】:2018-03-05 03:46:39 【问题描述】:

我有一个正在运行的 AWS Aurora 数据库集群,它 99.9% 都专注于写入。在高峰期,它将运行 2-3k 写入/秒。

我知道 Aurora 默认对写入进行了一些优化,但作为 AWS 的新手,我想问一下 - 使用 Aurora 的写入性能有哪些最佳实践/技巧?

【问题讨论】:

这不是关于编程的问题。在 dba.stackexchange.com 上询问可能更合适,而不是在 ***.com 上询问。我已投票决定将问题移至 dba 站点。 【参考方案1】:

根据我的经验,Amazon Aurora 不适合运行具有大量写入流量的数据库。至少在 2017 年左右实施。也许随着时间的推移会有所改善。

我在 2017 年初为一个写入繁重的应用程序进行了一些基准测试,我们发现,考虑到我们的应用程序和数据库,RDS(非 Aurora)在写入性能方面远远优于 Aurora。基本上,Aurora 比 RDS 慢了两个数量级。亚马逊声称 Aurora 的高性能显然完全是营销驱动的废话。

2016 年 11 月,我参加了在拉斯维加斯举行的 Amazon re:Invent 大会。我试图找到一位知识渊博的 Aurora 工程师来回答我关于性能的问题。我能找到的只有初级工程师,他们被命令重复声称 Aurora 比 mysql 快 5 到 10 倍。

2017 年 4 月,我参加了 Percona Live 会议,看到了一个关于如何使用标准 MySQL 和 CEPH 开发类似 Aurora 的分布式存储架构的演讲,用于开源分布式存储层。这里有一个关于同一主题的网络研讨会:https://www.percona.com/resources/webinars/mysql-and-ceph,由我在会议上发言的工程师 Yves Trudeau 共同主持。

将 MySQL 与 CEPH 一起使用变得很清楚的是,工程师必须禁用 MySQL change buffer,因为无法缓存对二级索引的更改,同时还要分配存储。这会导致写入具有辅助(非唯一)索引的表的巨大性能问题。

这与我们在使用 Aurora 对应用程序进行基准测试时看到的性能问题是一致的。我们的数据库有很多二级索引。

因此,如果您绝对必须将 Aurora 用于具有高写入流量的数据库,我建议您必须做的第一件事是删除所有二级索引。

显然,如果需要索引来优化某些查询,这将是一个问题。当然,SELECT 查询,还有一些 UPDATE 和 DELETE 查询都可能使用二级索引。

一种策略可能是制作 Aurora 集群的非 Aurora 只读副本,并仅在只读副本中创建二级索引以支持您的 SELECT 查询。我从来没有这样做过,但显然这是可能的,根据https://aws.amazon.com/premiumsupport/knowledge-center/enable-binary-logging-aurora/

但这仍然无助于您的 UPDATE/DELETE 语句需要二级索引的情况。我对这种情况没有任何建议。你可能不走运。

我的结论是,我不会选择将 Aurora 用于写入繁重的应用程序。也许将来会改变。


2021 年 4 月更新:

自从编写上述内容以来,我已经针对 Aurora 版本 2 运行了 sysbench 基准测试。我无法分享具体数字,但我得出的结论是,当前的 Aurora 改进更适合写入繁重的工作负载。我确实使用大量二级索引进行了测试以确保。但我鼓励任何认真考虑采用 Aurora 来运行自己的基准测试的人。

至少,Aurora 比使用 EBS 存储的传统 Amazon RDS for MySQL 要好得多。这可能就是他们声称 Aurora 比 MySQL 快 5 倍的地方。但 Aurora 并不比我测试过的其他一些替代方案快,而且实际上无法匹配:

MySQL 服务器自己安装在使用本地存储的 EC2 实例上,尤其是带有本地连接 NVMe 的 i3 实例。我知道实例存储不可靠,因此需要运行冗余节点。

MySQL 服务器自己安装在我们数据中心的物理主机上,使用直连 SSD 存储。

使用 Aurora 作为托管云数据库的价值不仅仅在于性能。它还具有自动监控、备份、故障转移、升级等功能。

【讨论】:

感谢您的洞察力。所有查询都在 Redshift 集群上卸载并完成,因此删除二级索引根本不应该成为问题,因为一般数据分析不会触及数据库。我以前没有听说过这个问题,但我会试一试,看看是否有什么不同。 哇,我可以确认是这种情况。删除二级索引几乎将 CPU 使用率降低了一半。似乎这是他们需要解决的问题。 很抱歉,我只能为你投票一次。这正是我试图阅读的真实用例体验,因为我正在考虑将一个类似的数据库迁移到 Aurora,我必须找出它是否有助于具有大量索引的写入繁重的应用程序. @IkerAguayo,那是几年前的事了,但我记得我正在开发的应用程序的写入与读取比率约为 80:1。这是非常不寻常的。大多数应用程序具有相反的比例,其中读取比写入更常见。即使写入与读取的比率为 1:1,我也会认为应用程序的写入量很大,因为即使这样,写入量也会比典型应用程序多得多。 @Juliano 感谢您分享您使用 AWS 的经验。自 2017 年以来,我已经完成了其他基准测试,因此我更新了上面的答案。【参考方案2】:

对于我的用例,我在使用 Aurora 时获得了相对积极的体验。我相信(时间已经过去)我们正在推动接近每秒 20k DML 的最大实例类型(我认为是 db.r3.8xlarge?)。为含糊而道歉,我不再有能力获得该特定系统的指标。

我们做了什么:

该系统不需要对给定的插入“立即”响应,因此写入被排入单独的进程。此过程将收集 N 个查询,并将它们分成 M 个批次,其中每个批次与一个目标表相关联。这些批次将放在一个 txn 中。

我们这样做是为了实现批量写入的写入效率,并避免跨表锁定。有 4 个独立的(我相信?)进程执行此出列和写入行为。

由于写入负载如此之高,我们绝对必须将所有读取推送到只读副本,因为主节点通常占用 50-60% 的 CPU。我们通过简单地创建随机数据写入器进程来预先审查这个架构,并在我们将实际应用程序提交给它之前对一般系统行为进行建模。

写入几乎都是INSERT ON DUPLICATE KEY UPDATE 写入,并且表有许多二级索引。

我怀疑这种方法对我们有用,仅仅是因为我们能够容忍信息出现在系统中与读者实际需要它之间的延迟,从而允许我们批量处理更高的数量。 YMMV。

【讨论】:

【参考方案3】:

对于 Google 员工:

Aurora 需要实时写入多个副本,因此必须有一个带有锁定、等待、检查机制的队列 这种行为不可避免地会导致 CPU 使用率超高,并且在有连续写入请求时会出现延迟,而这些请求只有在多个副本同步时才会成功 自 Aurora 成立以来一直存在这种情况,一直到 2020 年,如果我们要保持服务的低存储成本和公平计算成本,这在逻辑上即使不是不可能也很难解决 Aurora MySQL 的大容量写入性能可能比 RDS MySQL 差 10 倍以上(根据个人经验并由上述答案证实)

解决问题(更像是一种变通方法):

如果超过 5% 的工作负载正在写入,请小心使用 Aurora 如果您需要近乎实时的大量写入结果,请小心使用 Aurora @Bill Karwin 指出删除二级索引以提高写作水平 批量应用插入和更新可能会改进写作

我说的是“小心”而不是“不要使用”,因为许多场景都可以通过巧妙的架构设计来解决。数据库写入性能几乎无法依赖。

【讨论】:

以上是关于优化 AWS Aurora 实例的写入性能的主要内容,如果未能解决你的问题,请参考以下文章

扩展 AWS 预留实例(EC2、Elasticache、Aurora)

AWS Aurora RDS 中的集群和实例有啥区别

AWS-CLI:在从快照创建的现有集群中创建 RDS Aurora 数据库实例

Aurora依托AWS加速Aurora Driver的开发

Terraform AWS Aurora Serverless MySQL - 错误:无效的数据库引擎

从现有 RDS 数据库实例 (Aurora PostgreSQL) 创建 CloudFormation Yaml