如何使用 Azure 数据资源管理器构建多租户解决方案

Azure 数据资源管理器中的多租户概念是指为不同的租户提供服务并将其数据存储在单个群集中。

租户可以代表一个客户、一组用户或任何类别的用户,其数据需要沿租户边界进行隔离。 你还可以建立多级别的多租户方案,例如,各有多个租户的多个应用程序。 本文不会讨论此方案,但类似的原理广泛适用。

一个重要因素是最终用户访问其租户数据的方式。 当最终用户直接访问 Azure 数据资源管理器时,必须在 Azure 数据资源管理器中配置访问控制,以将用户的视图与其自己的数据隔离开来。 当代理应用程序访问 Azure 数据资源管理器中的用户数据时,该应用程序可以执行隔离。

本文将介绍一些部署体系结构并提供每种体系结构的特征。 可以使用这些特征来帮助确定哪种体系结构最适合你的解决方案。

近邻干扰

一般情况下,无论使用哪种体系结构,在多个租户之间共享一个群集都意味着不同的租户将共享该群集的资源。 这可能导致近邻干扰反模式。

例如,如果某个租户执行许多计算密集型查询或引入,其他租户可能会受到资源匮乏的影响。 可以使用工作负载组来缓解此问题。 还可以使用策略来控制缓存和总体存储。

体系结构概述

后续部分将详细介绍部署体系结构。 本部分对体系结构进行对比,以促进决策过程。

体系结构 优势
每个数据库一个租户 - 租户隔离:无需代理
- 每个租户可以有不同的策略,例如保留策略
- 每个租户的模式演变灵活性
- 轻松快速地删除租户数据
许多租户一个表 - 高效的数据合并和盘区管理
- 简化的模式演变
- 最适合具体化视图
- 非常适合分区
单一数据库中每个表一个租户 不建议使用

体系结构:为每个数据库使用一个租户

显示为每个数据库使用一个租户的体系结构的示意图。

这是一种流行且直接的体系结构。 每个租户获取自身的数据库。 每个数据库具有相同的架构。

此体系结构的特征是:

  • 预配新租户:需要创建新数据库并在其上部署架构实体

  • 删除租户:需要删除数据库。 删除一个数据库只需花费几秒钟时间。 消耗的资源极少且数量恒定,这些资源与租户的数据量不呈线性关系。

  • 数据库架构更新:每个租户可以在不同的时间独立更新。 访问数据库的应用程序必须了解与之交互的每个数据库的版本。

  • 保留和缓存策略:每个租户可以有自身独特的策略,使你能够为客户提供自定义的保留和缓存策略。

  • 每个租户的安全边界:

    • 对于多租户应用程序(代理):将应用程序配置为以相关数据库为目标。 对查询使用访问限制以禁止跨数据库查询
    • 对于拥有直接访问权限的用户:可以在数据库级别为用户授予访问权限。 为用户授予对其数据库的直接访问权限会导致依赖于实施细节,从而难以更改实施方案。 因此,我们强烈建议使用代理方法来访问数据库。
  • 大规模聚合多个租户的数据:使用联合运算符聚合数据库之间的数据。 但是,随着租户数量的增加,此方法可能会变得繁琐。 尽管从租户的角度看,聚合多个租户的数据可能是一项设计目标,但解决方案所有者可能希望聚合所有租户的数据以收集统计信息。

  • 分片化:每个租户为每个数据库表引入少量记录会导致创建较小的分片,而稍后需要合并这些分片。 这会提高分片管理成本。 因此,我们强烈建议使用流式引入,例如事件中心或事件网格引入。 若要使用流式引入,必须确保在群集和表上启用它。

  • 具体化视图和分区策略。 随着租户数量的增加,必须记住群集可以有效运行的具体化视图分区策略数量有限制。

  • 事件网格和事件中心数据连接:这些数据连接是按数据库创建的。 因此,此体系结构要求为每个租户提供一个数据连接和事件网格或事件中心实例,这增大了管理复杂性。 考虑为事件中心事件网格使用事件路由。

体系结构:许多租户一个表

显示为多个租户使用一个数据库的体系结构的示意图。

此体系结构为所有租户使用一个数据库,因此在整合性方面更加激进。 数据库中的每个表都有一个“租户 ID”列或等效列,允许筛选单个租户的数据。 可以按租户将表分区以提高查询性能,因为大多数查询可能会按租户进行筛选。 在可能的情况下,应考虑使用复合分区键对另一列进行分区。 例如,可以创建一个复合分区键,用于串联租户 ID 和其他列的值。

此体系结构的特征是:

  • 预配新租户:预配新租户不需要创建任何数据库或调整架构。 新的租户 ID 将在新记录中使用。

  • 删除租户:需要软删除清除租户的数据。 前者效率更高,而后者支持 GDPR 义务。 可以批量执行多个清除操作(例如在周末)以限制对资源消耗量的影响。

    注意

    本文介绍如何删除设备或服务中的个人数据,并且可用于为 GDPR 下的义务提供支持。 有关 GDPR 的常规信息,请参阅 Microsoft 信任中心的 GDPR 部分服务信任门户的 GDPR 部分

  • 数据库架构更新:所有租户的架构同时升级。 由于所有租户共享表,因此更改表架构会一次性更改所有租户。

  • 保留和缓存策略:所有租户的策略是相同的,因为它们共享同一个表。

  • 每个租户的安全边界:

    • 对于多租户应用程序(代理):使用 Restrict 语句
    • 对于拥有直接访问权限的用户:使用行级别安全性策略并熟悉其限制。 为用户授予对其数据库的直接访问权限会导致依赖于实施细节,从而难以更改实施方案。 因此,我们强烈建议使用代理方法来访问数据库。
  • 大规模聚合多个租户的数据:拥有足够访问权限的用户可以对多个租户的数据运行标准聚合查询。

  • 分片化:由于所有租户将数据引入同一个表中,因此数据通常可以整合,并高效地引入到一个或少量几个分片中。

  • 具体化视图和分区策略:这些功能可用于多租户表。 可以通过按“租户 ID”或等效列分区来提高性能。 有关详细信息,请参阅分区策略的方案

  • 事件网格和事件中心数据连接:由于所有租户的数据最终都会引入到一个表中,因此数据连接是整合的。

体系结构:为单个数据库中的每个表使用一个租户

显示为每个表使用一个租户的体系结构的示意图。

此体系结构是前面所述体系结构的组合,其中所有租户的数据最终都会引入单个数据库的不同表中。 此体系结构无法体现其他体系结构的所有优点。

尽管每个租户的数据是隔离的,但它们驻留在同一数据库的同一安全上下文中。 与多数据库体系结构一样,此体系结构可能会导致分片化。 每个租户的表名称不同,因此必须为每个租户自定义查询。