InfoScout 在 AWS 上诞生,从 2011 年出世以来一直稳步前行。它最初只是一个单一的 Amazon EC2 实例,用于收集朋友和家人上传的收据。七年之后,我们现在管理着 150 多个 AWS 实例,以支持我们的移动应用程序、数据管道、机器学习模型和我们的 SaaS 分析平台。本博文详细介绍了我们不断成长的基础设施以及面临的数据库迁移挑战。
我们的业务十分简单。我们提供多种移动应用程序,每天帮助消费者获取购物收据的照片,然后上传到云上。我们分析这一数据,然后向品牌、零售商、代理商、消费者和大众消费品 (CPG) 企业提供有关其顾客的深刻见解。这种以消费者为中心的大规模数据收集方法,有利于品牌最终回答许多问题背后的“为什么”。“为什么我的品类销售下降了 5%?” “品类的哪些消费者变化推动了我的品牌的销售?” “哪些类别的消费者在将消费转向线上?” 我们现在获取的信息占美国购物交易的 1/500,每天传输 300000 张收据图像。
为了支持在 AWS 上的整个基础设施和应用程序,我们经常使用 Amazon EC2、Amazon RDS、Amazon S3、Amazon VPC 和 Route 53 等产品。2011 年时,我们最初仅在加利福尼亚北部有一个 VPC,到 2016 年,我们不断扩展 AWS 上的足迹以满足不断增长的数据管道和客户需求。我们对 Amazon Aurora 和 AWS Lambda 感兴趣,但这些服务在我们所在区域并未开放,因此第一步是将我们的足迹迁移到俄勒冈区域。
2016 年 11 月和 12 月,我们迁移了超过 100 个服务器,包括多个数据库。我们在 AWS 上成长的第二阶段已然开始。
痛苦增加
与许多初创公司一样,我们面临了扩展问题,我们首要考虑的因素是提高数据库的吞吐量和性能。即使在迁移到俄勒冈区域前,随着我们的业务增长,我们已经开始遇到数据库性能问题。
InfoScout 的主要交易数据库是在一个 Amazon RDS for MySQL 实例中配置的。它作为我们的消费者数据库后端,存储了我们的所有手机用户数据、调查数据和收据数据。我们的配置包含单一主数据库和两个只读副本,都使用高可用性和 ETL 配置。随着数据库的增长,我们一直在纵向扩展实例,最终升级到了当时 Amazon RDS for MySQL 支持的最大实例型号。这种方法在最初非常奏效,但随着数据库增长到几个 TB 大小,我们看到高流量期间有两个重大问题爆发出来。
首先是查询执行时间的总体性能不佳。在高峰负载下,我们将收到太多并发请求,我们在 Amazon RDS 实例上的队列深度也显著倒退。我们看到 50、100 甚至 125 的队列深度,说明出现了 I/O 层面的运行阻滞。这导致读取速度下降,页面超时,作业失败。其次是存储也慢慢成为问题。Amazon RDS for MySQL 当时的最大存储容量为 6 TB(现在最高支持 16 TB),而我们的数据库已经达到了 5 TB。
由于这些性能和存储问题,我们开始花费宝贵的时间和资源来照顾 MySQL。每当高流量阶段发生问题时,我们将不得不关闭非关键的服务。这将减轻数据库的负载。持续的 Amazon CloudWatch 警报也影响了我们的其他职责。
我们评估了解决此问题的多种方案:对数据库集群进行分区,将它化整为零变为微服务,存档较老的数据,甚至迁移回 Amazon EC2 上的 MySQL。但这些方案似乎都过于复杂,鉴于我们的增长速度也不可持续。与客户经理和 AWS 解决方案架构师交流后,我们开始研究将兼容 MySQL 的 Aurora 作为主数据库的新目的地。
我们最初对 Aurora 还是有些担心。它相对较新,它的专有性质也与我们的其他架构组件不符,此外我们也怀疑它是否真的可以与 MySQL 数据库即插即用。但我们对它的可扩展性和功能组合深深吸引。更低的成本、更快的性能、低复制延迟和 64 TB 的最高存储容量,这意味着在近期不再需要对数据库进行分区。
迁移到 Aurora
在决定将生产数据库迁移到 Aurora 前,我们必须完成一些额外的兼容性检查,以及测试和调整暂存环境。
在我们移动后端的大约 250 个表中,大多数表都使用 MySQL InnoDB 存储引擎。十多个表则使用更老的 MyISAM 存储引擎(以支持原来的 FULLTEXT 搜索查询)。Aurora 兼容 InnoDB 但不兼容 MyISAM,这意味着我们必须立即将 MyISAM 表迁移到 InnoDB — 这是一项简单直接的工作。在此之后,我们将整个暂存环境都迁移到了 Aurora,并停止了 Amazon RDS for MySQL 暂存环境。
在接下来的 2-3 周内,我们测试、调整和监控了 Aurora 上的暂存环境的性能,一切看起来都不错。内部测试的暂存环境显然不会使用生产环境的流量。但从逻辑和 SQL 的角度,一切都异常顺利。对 Aurora 集群的调用也符合预期,数据的流动也非常正常。现在我们已经对 Aurora 与 MySQL 的兼容性十分放心。
2017 年夏季对暂缓环境开绿灯后,我们编制了迁移的检查清单。它似乎包括以下方面:
从 Amazon RDS for MySQL 主数据库建立两个 Aurora 只读副本
等待 Aurora 只读副本更新,这很快就完成了
关闭所有的消费者流量和我们的异步 Python Celery 队列
修改 MySQL 主实例密码以确认不会有流氓进程写入无辜的 MySQL 数据库
验证 Aurora 表已更新,并且无写入操作进入 MySQL 主实例
将一个 Aurora 数据库晋升为新的主数据库
更新 Route 53 DNS 记录以使数据库终端节点指向新的 Aurora 数据库
启动备份消费者应用程序、Celery 队列和其他服务
我们有许多 CloudWatch 控制面板监控队列、读取时间和写入时间、吞吐量和复制延迟数据。Aurora 集群开始升温,所有 CloudWatch 指标看起来都很正常。迁移似乎很成功,虽然这属于午夜,没有流量。我们认识到我们仍有可能会在我们批准迁移后收到警报。但在我们次日早上检查时,一切都非常顺利 — 我们可以直接宣布 Aurora 的表现棒极了。
结果
以下插图突出显示了切换之前和之后的执行时间和延迟 — 您可以看到性能的即刻提升。
我们非常喜欢 CloudWatch,有数十个指标来监控 Celery 工人的大型异步工场的表现。迁移到 Aurora 后,我们发现收据引擎状态计算机中的一个关键步骤的时间减少了 10 倍。此任务负责复制图像并验证最近提交的收据。下图显示了收据管道中的一个关键异步作业的运行时间。您可以看到执行时间下降了 10 倍,从 4 秒缩短至 400 毫秒。
除 AWS 监控工具外,我们还使用 New Relic 等生产级的服务来进行深度性能监控。我们提取了这些报告,看到响应时间立即缩短了 3 倍! 在我们使用 Amazon RDS for MySQL 时,完成手机客户端向我们的后端发出的标准网络调用将需要 600 毫秒,几乎所有时间都发生在 MySQL 查询中。部署 Aurora 后,这一延迟已经缩短至 200 毫秒以下。看到这些初步的指标后,我们的基础设施团队坚信我们为 6-TB 的交易数据集群找到了新家。下图显示了迁移之前和之后的延迟。您可以看出性能的即刻提升。
不断成长的数据库
在评估迁移还是重建数据库环境的方案时,我们考虑了多种因素。最终,因为所涉及的运行开销和基础设施管理问题,我们不希望走上分区或自建集群的道路。我们关心在数据库管理和运行上花费的时间会导致我们无法专注于功能开发、工程设计和帮助公司成长。这最终会损害我们的业务发展速度。
虽然 Aurora 看似是最合理的方案,但迁移的决定不能贸然做出。我们进行了一次集体团队讨论,研究迁移到 Aurora 是否是最合理的选择。MySQL 非常稳定、强健,已经使用了数十年 — 我们依然相信此技术。然而,我们拥有一个很大的数据库,每分钟传入的查询超过 20000 条,MySQL 本身无法消化这么大的压力。
如果您因任何原因考虑迁移,不要单纯追逐最热门的技术。以团队的方式评估和考虑您的所有可选方案。对现有生产环境进行压力测试,仔细记录问题。然后根据检查清单测试,测试,测试新的暂存环境。这种方法让我们收获不浅。迁移到 Aurora 后我们在继续增长,新的数据库以极高的性能稳定运行。我们很满意将 Aurora 作为新的数据库引擎,相信它能够随我们的业务发展不断扩展。
说到扩展,在未来几周,我们预计会庆祝收到第 5 亿张收据! 感谢 AWS 的团队让这一切成为可能。
InfoScout 应用程序架构
作者介绍:
Doug Flora 是 Amazon Web Services 的 高级 Amazon Relational Database Service (RDS) 产品经理。
本文转载自 AWS 技术博客。
原文链接:
评论