数据通常被视为解决方案中最有价值的部分,因为它表示你和客户的重要业务信息。 因此,悉心管理好数据至关重要。 为多租户系统规划存储或数据组件时,需要确定共享或隔离租户数据的方法。
在本文中,对于在确定多租户系统中的数据存储方法时对解决方案架构师至关重要的关键注意事项和要求,我们提供了相关指导。 随后,我们建议了一些用于将多租户应用于存储和数据服务的常见模式,以及一些要避免的反模式。 最后,我们为某些特定情况提供了有针对性的指导。
关键考虑因素和要求
从多种角度考虑用于存储和数据服务的方法非常重要,包括 Azure 架构良好的框架的支柱。
缩放
使用存储数据的服务时,应考虑拥有的租户数以及存储的数据量。 如果你有少量租户(例如五个或更少),并且为每个租户存储少量数据,那么规划高度可缩放的数据存储方法或构建完全自动方法来管理数据资源可能是白费力气。 但随着数量增长,你会越来越受益于具有明确的策略来缩放数据和存储资源,并将自动化应用于其管理。 如果有 50 个或更多租户,或者计划达到该缩放级别,那么设计数据和存储方法并将缩放作为关键考虑因素会尤其重要。
考虑计划缩放的程度,并明确规划数据存储体系结构方法以满足该缩放级别。
性能可预测性
多租户数据和存储服务特别容易受到近邻干扰问题的影响。 需考虑租户是否可能会影响彼此的性能,这十分重要。 例如在一段时间内,租户在使用模式中是否具有重叠峰值? 你的所有客户是否每天同时使用你的解决方案,或者请求是否均匀分布? 这些因素会影响需要设计的隔离级别、预配的资源量以及租户之间可共享资源的程度。
请务必在此决策过程中考虑 Azure 的资源和请求配额。 例如,假设部署单个存储帐户以包含租户的所有数据。 如果每秒超过特定数量的存储操作,则 Azure 存储会拒绝应用程序的请求,并且所有租户都会受到影响。 这称为限制行为。 对受限制的请求进行监视会十分重要。 有关详细信息,请参阅 Azure 服务的重试指南。
数据隔离
设计包含多租户数据服务的解决方案时,通常有不同的数据隔离选项和级别,它们各自具有自己的优势和权衡。 例如:
- 使用 Azure Cosmos DB 时,可以为每个租户部署单独的容器,并且可以在多个租户之间共享数据库和帐户。 或者,可能会考虑为每个租户部署不同的数据库(甚至是帐户),具体取决于所需的隔离级别。
- 对 blob 数据使用 Azure 存储时,可以为每个租户部署单独的 blob 容器,也可以部署单独的存储帐户。
- 使用 Azure SQL 时,可以在共享数据库中使用单独的表,也可以为每个租户部署单独的数据库或服务器。
- 在所有 Azure 服务中,可以考虑在单个共享 Azure 订阅中部署资源,也可以使用多个 Azure 订阅(甚至可以每个租户一个)。
没有单一解决方案可适用于每种情况。 选择的选项取决于许多因素和租户的要求。 例如,如果租户需要满足特定合规性或法规标准,则可能需要应用更高的隔离级别。 同样,你可能有以物理方式隔离客户数据的商业要求,或者可能需要强制实施隔离以避免近邻干扰问题。 此外,如果租户需要使用自己的加密密钥,他们具有单独的备份和还原策略,或者需要将其数据存储在不同的地理位置,则你可能需要将他们与其他租户隔离,或将他们与具有类似策略的租户分组在一起。
实现的复杂性
考虑实现的复杂性会十分重要。 好的做法是尽可能简单地保持体系结构,同时仍满足要求。 避免使用随着规模扩展而变得日益复杂的体系结构,或者没有资源或专业知识来进行开发和维护的体系结构。
同样,如果解决方案不需要扩展到大量租户,或者你不担心性能或数据隔离,则最好使解决方案保持简单,避免增加不必要的复杂性。
多租户数据解决方案方面的一个特别关注是你支持的自定义级别。 例如,租户是否可以扩展数据模型或应用自定义数据规则? 确保提前设计好这一需求。 避免为单个租户分支或提供自定义基础结构。 自定义的基础结构不支持进行缩放、测试解决方案,或部署更新。 而是考虑使用功能标志和其他形式的租户配置。
管理和操作的复杂性
考虑计划如何操作解决方案,以及多租户方法如何影响操作和过程。 例如:
- 管理:考虑跨租户管理操作,例如定期维护活动。 如果使用多个帐户、服务器或数据库,将如何为每个租户启动和监视操作?
- 监控和计量:如果对租户进行监视或计量,请考虑解决方案如何报告指标,以及它们是否可以轻松链接到触发请求的租户。
- 报告:跨隔离的租户报告数据可能需要每个租户将数据发布到集中式数据仓库,而不是单独对每个数据库运行查询,然后聚合结果。
- 架构更新:如果使用强制实施架构的数据库,请计划如何在资产中部署架构更新。 考虑应用程序如何知道要用于特定租户的数据库查询的架构版本。
- 要求:考虑租户的高可用性要求(例如,运行时间服务级别协议或 SLA)和灾难恢复要求(例如恢复时间目标或 RTO,以及恢复点目标或 RPO)。 如果租户有不同的期望,你是否能够满足每个租户的要求?
- 迁移:如果需要迁移到不同类型的服务、不同的部署或其他区域,如何迁移租户?
成本
通常,部署基础结构的租户密度越高,预配该基础结构的成本便越低。 但是,共享基础结构会增加出现问题(如近邻干扰问题)的可能性,因此请仔细考虑权衡。
要考虑的方法和模式
来自 Azure 体系结构中心的多个设计模式与多租户存储和数据服务相关。 可以选择始终遵循一种模式。 或者,可以考虑混合和匹配模式。 例如,你可能对大多数租户使用多租户数据库,但是为付款更多或具有异常要求的租户部署单租户缩放单元。 同样,使用部署缩放单元进行缩放通常是一种很好的做法,即使在缩放单元中使用多租户数据库或分片数据库时也是如此。
部署戳模式
有关如何使用部署缩放单元模式来支持多租户解决方案的详细信息,请参阅概述。
共享多租户数据库和文件存储
你可能会考虑部署共享多租户数据库、存储帐户或文件共享,并在所有租户间进行共享。
此方法为基础结构提供最高的租户密度,因此与任何方法相比,其成本往往是最低的。 它通常还会降低管理开销,因为只需管理、备份和保护单个数据库或资源。
但是,使用共享基础结构时,需要考虑几个注意事项:
- 缩放限制:依赖于单个资源时,请考虑该资源的受支持缩放和限制。 例如,如果体系结构依赖于单个数据库,则一个数据库或文件存储的最大大小或最大吞吐量限制最终会成为严苛的阻碍因素。 在选择此模式之前,请仔细考虑需要实现的最大缩放,并将它与当前和将来的限制进行比较。
- 近邻干扰:近邻干扰问题可能会成为一个因素,尤其是在租户特别繁忙或生成比其他人更高的工作负载时。 考虑应用限制模式或速率限制模式来缓解这些影响。
- 监视每个租户:可能难以为单个租户监视活动和度量消耗。 某些服务(例如 Azure Cosmos DB)会为每个请求提供资源使用情况报告,因此可以跟踪此信息以度量每个租户的消耗。 其他服务不提供相同的详细信息级别。 例如,用于文件容量的 Azure 文件指标是按文件共享维度提供的,而且只有在使用高级共享时才可用。 但是,标准层仅在存储帐户级别提供这些指标。
- 租户需求:租户对安全性、备份、可用性或存储位置可能有不同的需求。 如果这些要求与单个资源的配置不匹配,则可能无法满足它们。
- 架构自定义:使用关系数据库时或是在数据架构非常重要的其他情况下,租户级别架构自定义会难以实现。
分片模式
分片模式涉及部署每个包含一个或多个租户数据的多个单独数据库(称为分片)。 与部署缩放单元不同,分片并不意味着整个基础结构都是重复的。 可以对数据库进行分片,而不对解决方案中的其他基础结构进行复制或分片。
分片与分区密切相关,这两个术语通常可交换使用。 请考虑水平数据分区、垂直数据分区和功能数据分区指导。
分片模式可以扩展到非常大量的租户。 此外,根据工作负载,你可能能够对分片实现较高的租户密度,因此成本可能会很有吸引力。 分片模式还可用于解决 Azure 订阅和服务配额、限制和约束。
某些数据存储(例如 Azure Cosmos DB)可为分片或分区提供本机支持。 使用其他解决方案(例如 Azure SQL)时,对于给定租户,构建分片基础结构并将请求路由到正确的分片可能会更加复杂。
分片还使得难以支持租户级配置差异,让客户很难提供自己的加密密钥。
每个租户各有专用数据库的多租户应用
另一种常见方法是部署单个多租户应用程序,其中每个租户各有专用数据库。
在此模型中,每个租户的数据与其他租户隔离,你可能能够对每个租户支持某种程度的自定义。
因为会为每个租户预配专用数据资源,所以此方法的成本可能高于共享托管模型。 但是,Azure 提供了多个可以考虑的选项,以便跨多个租户分摊托管单个数据资源的成本。 例如,使用 Azure SQL 时,可以考虑弹性池。 对于 Azure Cosmos DB,可以为数据库预配吞吐量,并在该数据库中的容器之间共享吞吐量,不过当你需要保证每个容器的性能时,此方法并不合适。
在此方法中,由于仅为每个租户单独部署数据组件,因此你可能可以为解决方案中的其他组件实现较高密度,并降低这些组件的成本。
为每个租户预配数据库时,请务必使用自动部署方法。
地理节点模式
地理节点模式专为地理分布式解决方案而设计(包括多租户解决方案)。 它支持高负载和高级别的复原能力。 实施“地理节点”模式时,数据层必须能够跨地理区域复制数据,并且它应支持多地理位置写入。
Azure Cosmos DB 提供多区域写入以支持此模式,Cassandra 支持多区域群集。 其他数据服务通常无法在不进行重大自定义的情况下支持此模式。
要避免的反模式
创建多租户数据服务时,需避免使你无法缩放的情况,这十分重要。
对于关系数据库,这些情况包括:
- 基于表的隔离。 在单个数据库中工作时,请避免为每个租户创建单个表。 使用此方法时,单个数据库无法支持大量租户,并且查询、管理和更新数据会变得越来越困难。 相反,请考虑使用具有租户标识符列的单个多租户表集。 或者,可以使用上述模式之一为每个租户部署单独的数据库。
- 列级别租户自定义。 避免只适用于单一租户的架构更新。 例如,假设你有单个多租户数据库。 避免添加新列以满足特定租户的要求。 对于少量自定义项而言,这可能是可以接受的,但是当你要考虑大量自定义项时,这很快会变得无法管理。 相反,请考虑修改数据模型以在专用表中跟踪每个租户的自定义数据。
- 手动更改架构。 即使只有单个共享数据库,也需避免手动更新数据库架构。 这容易失去对已应用的更新的跟踪,如果需要横向扩展到更多数据库,则难以标识要应用的正确架构。 相反,请构建自动管道来部署架构更改,并始终如一地使用它。 可在专用数据库或查阅表中跟踪用于每个租户的架构版本。
- 版本依赖项。 避免让应用程序依赖于单一版本的数据库架构。 进行缩放时,可能需要在不同时间为不同租户应用架构更新。 相反,请确保应用程序版本与至少一个架构版本向后兼容,并避免破坏性架构更新。
数据库
有一些功能可用于多租户。 但是,这些功能并非在所有数据库服务中都可用。 在确定要用于方案的服务时,请考虑是否需要这些功能:
- 行级别安全性可以为共享多租户数据库中的特定租户数据提供安全隔离。 此功能在 Azure SQL 和 Postgres Flex 中可用,但在其他数据库(如 MySQL 或 Azure Cosmos DB)中不可用。
- 可能需要租户级别加密以支持为其数据提供自己的加密密钥的租户。 此功能在 Azure SQL 中作为 Always Encrypted 的一部分提供。 Azure Cosmos DB 提供帐户级别的客户管理的密钥,并且支持 Always Encrypted。
- 资源池提供在多个数据库或容器之间共享资源和成本的功能。 此功能在 Azure SQL 的弹性池和托管实例以及 Azure Cosmos DB 的数据库吞吐量中可用,不过每个选项都具有你应注意的限制。
- 分片和分区在某些服务中具有比其他服务更强的本机支持。 Azure Cosmos DB 通过使用其逻辑和物理分区提供了这一功能。 虽然 Azure SQL 不以本机方式支持分片,但它提供分片工具以支持此类型的体系结构。
此外,在使用关系数据库或其他基于架构的数据库时,请考虑在维护数据库群时应在何处触发架构升级过程。 在小型数据库中,你可能会考虑使用部署管道部署架构更改。 随着数据库数量的增加,应用程序层最好能检测特定数据库的模式版本并启动升级过程。
文件和 blob 存储
请考虑用于隔离存储帐户中的数据的方法。 例如,可以为每个租户部署单独的存储帐户,也可以共享存储帐户并部署单个容器。 或者,可以创建共享 blob 容器,然后使用 blob 路径分隔每个租户的数据。 请考虑 Azure 订阅限制和配额,并仔细规划增长以确保 Azure 资源缩放以支持将来的需求。
如果使用共享容器,请仔细规划身份验证和授权策略,以确保租户无法访问彼此的数据。 在向客户端提供对 Azure 存储资源的访问权限时,请考虑使用附属密钥模式。
成本分配
请考虑如何度量消耗并将成本分配给租户,以便使用共享数据服务。 尽可能使用内置指标,而不是计算自己的指标。 但是,使用共享基础结构时,很难拆分单个租户的遥测数据,因此可能需要考虑使用应用程序级自定义计量。
通常,云原生服务(如 Azure Cosmos DB 和 Azure Blob 存储)可提供更精细的指标,用于对特定租户的使用情况进行跟踪和建模。 例如,Azure Cosmos DB 提供每个请求和响应消耗的吞吐量。
作者
本文由 Microsoft 维护, 它最初是由以下贡献者撰写的。
主要作者:
- John Downs | 首席软件工程师
其他参与者:
- Paul Burpo | FastTrack for Azure 首席客户工程师
- 丹尼尔·斯科特-伦斯福德|高级合作伙伴技术解决方案顾问
- 阿森·弗拉基米尔斯基|首席工程师,FastTrack for Azure
若要查看非公开的 LinkedIn 个人资料,请登录到 LinkedIn。
后续步骤
有关多租户和特定 Azure 服务的详细信息,请参阅: