亚马逊AWS官方博客

使用 Amazon DynamoDB 全局表构建弹性应用程序:第 1 部分

Original URL:https://aws.amazon.com/blogs/database/part-1-build-resilient-applications-with-amazon-dynamodb-global-tables/

对于需要构建弹性应用程序并尽可能降低恢复时间目标(RTO,Recovery Time Objective)和恢复点目标(RPO,Recovery Point Objective)的客户,他们希望充分利用 AWS 全球基础设施来支持其弹性目标。使用单个 AWS 区域中的多个可用区构建应用程序可以提供较高的可用性水平,但您可能面临着业务或监管要求,需要探索在多个区域中运行应用程序。切换到多区域设计是对架构和操作的重大转变,而在这个转变过程中,处理持久性层(数据库)是颇具挑战性的部分。在分为四个部分的这一系列博文中,您将学习如何使用 Amazon DynamoDB 全局表作为持久性层来构建弹性应用程序。第 1 部分(本文)演示了一个示例应用程序,并讨论了在迁移到多区域时可用性的变化。 第 2 部分介绍了 DynamoDB 在单区域和多区域环境中操作的特性。 第 3 部分介绍了第 1 部分中演示的示例应用程序的多区域模式。 第 4 部分最后分析了多区域模式,重点介绍操作。在这一系列文章中,您将看到对 Amazon Builder’s Library 中的几篇文章以及对 GitHub 中示例代码的引用。

示例应用程序

首先,让我们考虑一个示例应用程序,它使用 DynamoDB 实现持久性,使用 AWS Lambda 函数实施业务逻辑,并使用 Amazon API Gateway 向外部用户提供接口(如下图 1 所示)。在此示例中,您在 us-west-2 区域中部署应用程序。

图 1:部署在一个区域中的示例应用程序架构

图 1:部署在一个区域中的示例应用程序架构

该示例是一个简单的订单处理应用程序,提供了两个方法:用于创建订单的 POST 方法和用于检索订单的 GET 方法。要创建订单,应用程序必须验证下订单的客户存在,产品存在且有现货。

以下图 2 所示的基本架构基于 DynamoDB 事务示例。它包括三个表:一个用于客户,另一个用于订单,第三个用于产品目录。分区键分别是客户 ID、订单 ID 和产品 ID。创建订单时,您需要确认客户 ID 有效并且商品有现货,将商品标记为售出,最后创建订单。读取订单时,您从订单表中读取订单,并从产品目录表中读取相关产品详细信息。

图 2:基本架构

图 2:基本架构

区、区域和全球服务

在讨论示例应用程序的理论可用性之前,我们先回顾一下区、区域和全球服务之间的差异。

有些 AWS 服务限定在区中,这意味着该服务提供的资源仅限于单个可用区。Amazon Elastic Compute Cloud(Amazon EC2)就是一个例子。EC2 运行在特定的区中。如果您的应用程序中使用了 EC2 实例,并且该区域发生了可用性事件,那么您的应用程序可能会受到影响,除非您在其他区中设置了资源。利用 Elastic Load Balancing 等 AWS 服务以及自动扩缩组等功能,应用程序可以更轻松地跨多个区域并承受单个区域中的可用性事件。另请注意,可用性事件很少意味着整个区出现故障;可用性事件可能更多地涉及到日常问题,例如服务中的错误率升高。

另一些 AWS 服务是区域性的,这意味着该服务提供的资源分布在一个区域内,这样单个可用区出现故障时它们可以继续运行。提供持久性的服务会跨多个区复制数据。

例如,DynamoDB 在一个区域的三个可用区之间复制数据。如果您的应用程序完全使用区域服务,则不必担心区故障。

还有一些 AWS 服务是全球性的。例如,如果您在 Amazon Route 53 中创建了一条 DNS 记录,该服务会自动使记录在全球范围内可用。Route 53 资源并未限定在单个区域。

计算可用性

务必需要明确,理论上的可用性计算会假定故障事件是相互独立的,而软件或操作错误通常不会遵守这种假设。而且静态稳定性实践同样也很重要。静态稳定性要求在故障事件期间,应用程序的工作方式与正常运行期间的运行方式相同。例如,如果应用程序在三个可用区中运行,您可能会将基础容量平均分配给所有三个可用区。如果其中一个可用区出现故障事件,您可以计划增加另外两个可用区的容量来补偿。但是该计划假定了底层控制面板 API 运行正常,可以预置额外的容量。在这种情况下,更具弹性的设计是在每个可用区预置 50% 的容量,尽管成本会增加。

在本文的其余部分中,我在计算理论可用性水平时,只考虑了示例应用程序使用的 AWS 服务。许多 AWS 服务提供可用性服务等级协议(SLA,Service Level Agreement),但这并不保证可用性,而是定义了这样一些条件,如果服务未能满足其 SLA,那么您就有资格享受服务抵扣金。

在单区域案例中,DynamoDB 为标准表提供 99.99% 的 SLA,API GatewayLambda 均提供 99.95% 的 SLA。您的应用程序使用的 AWS 服务,在单个区域中满足其 SLA 的概率如下所示:

P(DynamoDB 满足 SLA)* P(API Gateway 满足 SLA)* P(Lambda 满足 SLA)

99.99% * 99.95% * 99.95% = 99.89%

为了进行比较,假设您使用 Amazon EC2 而不是 Lambda 进行计算,并且使用单个可用区。在这种情况下,Amazon EC2 SLA 为 99.5%。那么,应用程序的可用性如下所示:

P(DynamoDB 满足 SLA)* P(API Gateway 满足 SLA)* P(EC2 实例满足 SLA)

99.99% * 99.95% * 99.5% = 99.44%

通过使用区域服务而不是仅在单个可用区中提供的资源,应用程序的复合可用性从大约两个 9 提高到三个 9。如果您改为使用 DynamoDB 全局表并在多个区域中运行应用程序,会出现什么情况? DynamoDB 全局表的 SLA 为五个 9。假设您使用 Route 53 将用户流量路由到最近的区域。Route 53 现在的 SLA 为 100%

现在,在计算应用程序的复合可用性水平时,您的应用程序使用的 AWS 服务满足其 SLA 的概率如下所示:

P(Route 53 满足 SLA)* P(DynamoDB 全局表满足 SLA)* P(至少一个区域满足 SLA)

请注意,这些联合概率计算中假设这三个概率是独立的。因为每个区域都是独立的,所以从 AWS 的角度来看,这是一个合理的假设。同样请注意,软件或操作故障很可能不遵守这些最初的假设。

您在至少一个区域中使用的 AWS 服务达到其 SLA 的概率是多少? 首先,我们来定义 API Gateway 和 Lambda 在单个区域满足其 SLA 的概率:

P(API Gateway 满足 SLA)* P(Lambda 满足 SLA)= 99.95% * 99.95% = 99.9%

如果您有两个区域,则至少有一个区域满足 SLA 的概率如下所示:

1 – P(两个区域均未满足SLA)= 1 – (0.1% * 0.1%) = 99.9999%

因此,在使用两个区域的情况下,您的应用程序可以使用所需 AWS 服务的概率如下所示:

100% * 99.999% * 99.9999% = 99.9989%

按照相同的逻辑,在使用三个区域情况下的概率为 99.999%。可以合理地得出结论,使用两个区域可以获得非常接近五个 9 的概率,而三个区域则更接近于这一概率。实际上,选择使用哪个区域取决于分散在不同地理位置上用户群的弹性、成本和性能。本系列的第 3 部分中介绍的多区域模式可以扩展为涵盖两个以上的区域。

Amazon Builder’s Library 的文章 Minimizing correlated failures in distributed systems(最大限度减少分布式系统中的关联故障)深入分析了如何减少会影响多区域设计的关联故障类型。使用区域而不是单个可用区有助于防止单个区域中的基础设施问题,不过本文还讨论了减少非基础设施事件。我们将在第 4 部分中讨论部署管道时再次回到这一主题。

结论

在这篇文章中,您了解了区、区域和全球服务之间的区别,以及它们会如何影响简单的示例应用程序的可用性。在本系列的第 2 部分中,您将了解 DynamoDB 的一些重要特性以及它们与使用多区域的关系。

特别感谢为这篇文章做出了贡献的 Todd Moore、Parker Bradshaw 和 Kurt Tometich。


关于作者

Randy DeFauw 是 AWS 的高级首席解决方案架构师。他拥有密歇根大学电气工程硕士学位,其研究方向为自动驾驶汽车计算机视觉。他还拥有科罗拉多州立大学的工商管理硕士学位。Randy 曾在技术领域担任过各种职位,涉及的领域从软件工程直到产品管理。他于 2013 年进入大数据领域,不断探索该领域。他积极参与 ML 领域的项目,并在 Strata 和 GlueCon 等许多会议上发表演讲。