新闻中心

  • Home
  • 扩展您的 SaaS 关系数据库,第二部分:分片和路由 数据库博客

扩展您的 SaaS 关系数据库,第二部分:分片和路由 数据库博客

扩展您的关系数据库以支持SaaS:分片与路由

by Dave Roberts 和 Josh Hart 于 2024 年 4 月 30 日在 高级 (300)、Amazon Aurora、Amazon RDS、SaaS、技术教程 永久链接 评论 分享

关键要点

本文是关于如何为软件即服务SaaS扩展关系数据库系列的第二部分,深入探讨分片和路由的挑战。关于如何选择分片键及其对数据库架构的影响。分片可以提升性能并支持更复杂的多租户架构,但也会引入操作上的复杂性。使用像 AWS Aurora Limitless Database 这样的托管解决方案可以简化路由和扩展操作。

本文是关于如何为软件即服务SaaS扩展关系数据库系列的续集。SaaS 提供商通常会在其解决方案中使用关系数据库,例如 Amazon Relational Database ServiceAmazon RDS和 Amazon Aurora。在 第一部分 中,我们讨论了一些常见的扩展或优化关系数据库架构的方法,这些方法集中在扩展有限的物理资源集上,比如 垂直扩展 或 使用只读副本的水平扩展。作为SaaS提供商,您可能需要超越这些限制,此时 数据库分片 可以成为一个有效的扩展机制。

数据库分片增加了复杂性,一旦实施,通常就很难回头。这是因为分片会明确地融入数据模型中,应用程序也需修改以适应这种变化。因此,在做出可能影响您 SaaS 运营的决定之前,您应理解分片对数据库的影响。此外,随着您的数据库架构日益复杂,您还可能面临将租户请求路由到正确数据库的挑战。

在本文中,我们将探讨数据库分片及如何处理应用程序将租户请求路由到正确数据库的挑战。

进一步扩展

垂直扩展提高了读写性能,但您的数据库实例的规模或优化是有上限的。同样,使用只读副本的水平扩展让您可以为读取工作负载扩展,但您的数据库解决方案支持的只读副本数量也是有限的。当您接近或达到这些限制时,您将如何继续扩展应用程序?

在 池模型和桥接模型 中,当您有一些租户消耗的资源超过其他租户时,一种选择是将这些租户迁移到独立存储。通常被选中的租户是那些性能要求最高的。接下来,您需要引入机制以将现有租户迁移到新环境。诸如 AWS 数据库迁移服务AWS DMS等工具可以帮助 自动化这种迁移。此外,您还需要将租户映射到它们的存储,这为您的解决方案和操作增加了额外的复杂性。

另一种选择是使用数据库分片。这将允许您保持您的分区模型,并随着客户基础的增长扩展您的数据集。

SaaS 解决方案中的数据库分片

关于数据库分片的深入讨论请参见 什么是数据库分片? 和 使用 Amazon Relational Database Service 的分片。如果您对该概念不熟悉,我们建议您先参考这些资料,因为本文将重点关注与 SaaS 相关的内容。

在设计您的数据库分片架构时,您选择的分片键至关重要。SaaS 提供商通常使用 tenantid 作为分片键,因为这可以将租户的数据局限在单个数据分片中。以下图示是使用 tenantid 作为分片键对关系数据库中的订单表进行分片的示例。

通过将所有与某个租户相关的事务限制在一个数据分片中,您可以提高每个租户的性能。例如,针对某个租户的数据库查询必须搜索所有数据库中的所有行。通过将租户限制在单个数据库中,您减少了搜索的行数,从而提高了性能。它还提供了使用外键和连接JOIN的能力。以下图示显示了在多个数据库表中进行分片,使用 tenantid 作为分片键。

因为一个数据分片是一个独特的数据库,您可以在单个数据库实例或集群中拥有多个分片。您的分片大小和每个实例的分片数量将取决于您的用例。例如,您可能选择每个实例一个大的分片,以减少管理多个分片的运营开销。或者,如果由于数据库大小引发了问题,例如复制延迟或备份延迟,或者在执行数据库维护任务如 清理vacuuming时遇到困难,您可能会希望每个实例拥有多个较小的分片。

分片的好处

通过分片,您可以将应用程序扩展到单个数据库的性能极限之上。您可以以一种方式设计您的SaaS应用程序,使其能够在实时中调整现有分片的大小或添加新的分片,以解决性能问题,或响应新配置的租户。如果一个单独的租户所需性能超过单个数据库能提供的水平,分片则是可能的解决方案之一。

在涉及大量租户的情况下,使用分片的池模型可能比独立模型在运营上更高效。您管理的数据库数量更少,并且租户上线的流程更加简化,因为您无需为每个新租户配置新的数据库。

使用 tenantid 作为分片键还带来了其他操作效率。它与租户隔离方法很好地对齐,也很容易根据需要在新节点之间重新平衡租户,以解决性能问题,因为您将所有数据存储在单个数据分片上。类似地,每个租户的备份与恢复无需确保多个数据分片之间的一致性。

鲨鱼加速器免费

将分片与其他数据库扩展方法结合使用可以进一步提高使用 tenantid 作为分片键时的租户性能,尽管这样会增加复杂性。例如,您可以基于 tenantid 实施 表分区 以针对单个租户的性能,或引入 数据库缓存 以提升分片性能。

分片还提供了 细胞架构 模式。这限制了基础设施故障的影响范围,并减少了单个租户对其他租户性能的影响。以下图示展示了每个数据库实例包含三个分片的架构,每个分片最多包含两个租户,其中每个分片都是一个独特的数据库。该图示没有显示高可用性,这是 Aurora 或 Amazon RDS 原生实现的。有关这些选项的更多信息,请参考 高可用性和耐久性 和 Amazon RDS 多可用区。

通过 随机分片,您可以进一步减小单个有问题的租户对其他租户的影响。然而,这会增加复杂性,因为您需要引入一种管理分片复制的解决方案。

分片的挑战

分片为您的SaaS应用程序引入了显著的复杂性。应用程序必须处理所有分片之间数据的映射和路由。引入辅助服务可以帮助将这种复杂性隐藏在开发者之后。我们将在文章后面对此概念进行讨论。

需要从多个分片提取数据的查询需要额外的应用级工程。这通常导致比单个分片的查询更高的延迟。一些工作负载不适合分片,比如在线分析处理OLAP,在这些场景下,您通常在整个数据集上进行数据分析。在这些情况下,通常的做法是在OLAP数据库上创建数据集的副本,以实现两种能力。

分片还会引入多项操作上的挑战。技术支持可能会更加困难,因为数据集的足迹变得更复杂。分布式特性使得监控更加复杂,要求您具备租户感知的上下文、日志记录和计量。迁移租户也并非易事,可能需要更多的思考来考虑数据保存的策略。

随着时间的推移,分片的数据集可能会变得不均衡,并可能引入数据库热点。不同分片之间的性能差异可能导致客户体验不一致,因此需要持续地对租户进行重新均衡以保持数据的均匀分布,因此核心架构中必须具备迁移租户的能力。

确保您对分片架构具有可观测性至关重要。像 Amazon RDS 性能洞察、增强监控 和 Amazon DevOps Guru for RDS 等工具可以提供关于数据库性能的可视性,并帮助您识别可能影响解决方案的问题。

最后,将基于分片的架构还原为未分片架构非常困难,需要相当大的技术专业知识、工程资源和项目管理。您应该将分片的决定视为一扇单行门。

许多这些挑战可以通过 Amazon Aurora Limitless Database目前在预览中来解决。Aurora Limitless Database 是 Aurora 的无服务器部署,能够超越单个实例的限制。与实施您自己应用层的分片不同,Limitless Database 提供了一个单一接口,因此您的应用程序的使用方式与它使用单个数据库相似。使用 Aurora Limitless Database,您的应用程序无需处理租户路由或知道集群的拓扑结构。Aurora Limitless Database 知道架构和关键范围位置,以将查询路由到正确的数据访问分片并在返回到应用程序之前聚合结果。

何时进行分片以及如何处理分片

分片的主要好处是它可以让您超越单个物理数据库的规模。随着现代数据库资源的不断增长,通常当其他扩展方法不再可行时,才考虑采用分片。一种用例可能是独立模型中的租户已经达到了他们数据库的物理限制,无法以其他方式进行扩展。或者,您也可能达到数据库引擎性能的限制,希望保留现有的分区模型。我们建议您阅读 第一部分 ,以了解如何提高您的SaaS应用程序的关系数据库性能。

另一个考量分片的用例是大规模操作流程的高效性。当您有许多租户时,您可能会发现以独立模型管理这些租户的运营复杂性与分片池模型几乎相当,但没有池模型带来的成本效益。例如,在管理 400 个租户与 16 个数据库分片的情况下,可能比管理 400 个独立数据库要容易。

您还可以考虑分片来增强韧性。您的数据库架构可能能够支持许多租户。然而,数据库故障的影响可能对于您的业务来说太大,无法承担。分片的物理隔离减少了任何数据库故障的影响范围,复制可以在故障事件期间从次级分片启用数据的可用性。

如果您决定对数据集进行分片,您需要评估如何以及将哪些数据进行分片。您可能会将数据集拆分成几个部分,只分片需要分片的部分。评估您的SaaS应用程序功能和租户使用模式,以确定哪些数据集部分适合分片,然后将特定部分的数据集进行分片。

在复杂数据集中的数据库请求路由

在实施自己的分片解决方案时,应用程序需要知道如何路由对数据库的请求。当您将数据集分散到多个数据库分片或分区模型如独立模型中的高级层和池模型中的标准层时,这可能会变得具有挑战性。

扩展您的 SaaS 关系数据库,第二部分:分片和路由 数据库博客

应用程序需要一个索引,将每个租户映射到其数据库实例,以追踪租户数据的位置。在您上线新租户或在分片或分区模型之间迁移现有租户时,需要更新此索引。您可能还希望拥有一个机制来决定新租户将放置在哪个分片上。

您可以实现数据访问管理器作为辅助服务,管理和查询此索引。这将把数据集的复杂性隐藏在开发者之后,让您在未来更改数据集架构时无须修改您的应用程序。它不限于管理关系数据库,还可以索引和映射您应用程序的所有数据集。

以下图示展示了数据访问管理器的示例架构。

在此示例中:

我们有一个通过我们的SaaS应用程序传递的 JSON Web Token JWT,其中包含我们的 租户上下文。我们将 JWT 传递给数据访问管理器,该管理器调用 JWT 管理器。JWT 管理器检查 JWT 并返回 tenantid 字段。数据访问管理器使用 tenantid 映射到正确的数据库实例,使用存储在 Amazon DynamoDB 表中的映射。数据库详情返回给我们的应用程序。我们的应用程序然后连接到正确的数据库实例。

我们使用 DynamoDB 作为映射表,因为它提供了一个具有成本效益且可扩展的解决方案来存储映射数据。由于该映射数据可能被您应用程序中的所有服务和微服务使用,确保它不会成为性能瓶颈尤为重要。DynamoDB 很适合这种键值类型的访问模式,因为每个查询仅返回单个项目。若您的多个服务都使用这个分片模型,您可以通过添加一个 serviceid 属性并创建一个 复合主键 来扩展该示例架构。此外,您还可以引入 缓存层 来减少对 DynamoDB 的调用次数,因为这些数据预计会非常静态。

发表评论