你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

多租户解决方案中的计算体系结构方法

大多数基于云的解决方案由某种计算资源组成,例如 Web 和应用程序层、批处理器、计划作业,甚至 GPU 和高性能计算 (HPC) 等专用资源。 多租户解决方案通常受益于共享计算资源,因为基础结构中的租户密度更高可以减少运营成本和管理工作。 应考虑共享基础结构的隔离要求和影响。

本文提供有关解决方案架构师在规划多租户计算层时必须考虑的注意事项和要求的指导。 这包括将多租户应用于计算服务的一些常见模式,以及一些要避免的反模式。

关键考虑因素和要求

多租户和所选的隔离模型会影响计算资源的缩放、性能、状态管理和安全性。 本部分将回顾在规划多租户计算解决方案时必须做出的一些重要决策。

缩放

系统需要在不断变化的需求下保持足够的性能。 随着租户数量和流量的增加,你可能需要增加资源容量,以跟上不断增长的租户数量并保持可接受的性能比率。 同样,当活跃用户数量或流量减少时,应自动减少计算容量以降低成本,但应在对用户影响最小的情况下减少容量。

如果为每个租户部署专用资源,则可以灵活地独立缩放每个租户的资源。 在多个租户之间共享计算资源的解决方案中,如果缩放这些资源,则所有这些租户都可以利用新的规模。 但是,当规模不足以处理这些租户的整体负载时,这些租户也会受到影响。 有关详细信息,请参阅近邻干扰问题

构建云解决方案时,可以选择是要水平缩放还是垂直缩放。 在租户数量不断增加的多租户解决方案中,水平缩放通常可以提供更大的灵活性和更高的总体规模上限。

通常在应用程序处于负载状态时才会发现性能问题。 可以使用完全托管的服务(例如 Azure 负载测试)来了解应用程序在承压情况下的行为方式。

缩放触发器

无论使用哪种方法进行缩放,通常都需要规划导致组件缩放的触发器。 共享组件时,请考虑使用资源的每个租户的工作负载模式,以确保预配容量能够满足所需的总容量,并最大程度地减少租户遇到近邻干扰问题。 你还可以通过考虑租户数量来规划缩放容量。 例如,如果你要衡量用于为 100 个租户提供服务的资源,则在加入更多租户时,可以计划为每增加 100 个租户,就将资源扩展一倍。

状态

计算资源可以是无状态的,也可以是有状态的。 无状态组件不保留请求之间的任何数据。 从可伸缩性的角度看,无状态组件通常很容易横向扩展,因为你可以快速添加新的工作器、实例或节点,并且它们可以立即开始处理请求。 如果体系结构允许的话,则你还可以重新利用分配给一个租户的实例并将其分配给另一个租户。

有状态资源可以根据它们保留的状态类型进一步划分。 持久性状态是需要永久存储的数据。 在云解决方案中,应避免在计算层中存储持久性状态。 请改用数据库或存储帐户等存储服务。 暂时性状态是暂时存储的数据,包括只读的内存中缓存和本地磁盘上的临时文件存储。

暂时性状态通常可以帮助通过减少对后端存储服务的请求数量来提高应用层的性能。 例如,当你使用内存中缓存时,也许能够处理读取请求,而无需连接到数据库,且无需执行最近在处理另一个请求时执行的资源密集型查询。

在延迟敏感型应用程序中,缓存合成的成本可能很高。 如果每个租户需要缓存不同的数据,则多租户解决方案可能会使此问题变得更严重。 为缓解此问题,某些解决方案使用会话亲和性来确保针对特定用户或租户的所有请求由同一个计算工作器节点处理。 尽管会话亲和性可以提高应用层有效使用其缓存的能力,但也会导致缩放以及平衡工作器之间的流量负载变得更困难。 需要谨慎做出这种权衡。 许多应用程序不需要会话亲和性。

还可将数据存储在 Azure Cache for Redis 等外部缓存中。 外部缓存针对低延迟数据检索进行了优化,同时可以保持状态与计算资源的隔离,因此可以单独缩放和管理这些资源。 在许多解决方案中,使用外部缓存可以提高应用程序性能,同时保持计算层的无状态性。

重要

每当使用内存中缓存或其他保留状态的组件时,都应避免在租户之间泄漏数据。 例如,考虑在所有缓存键的前面附加一个租户标识符,以确保每个租户的数据是隔离的。

隔离

设计多租户计算层时,通常需要考虑采用许多不同的选项在租户之间进行某种级别的隔离,包括部署共享计算资源供所有租户使用、部署专用计算资源供每个租户使用,或部署介于这两个极端之间的某种资源。 每个选项各有利弊。 为了帮助确定哪个选项最适合你的解决方案,请考虑隔离要求。

你可能会关心租户的逻辑隔离,以及如何分离适用于每个租户的管理责任或策略。 或者,你可能需要为特定的租户部署不同的资源配置,例如部署特定的虚拟机 SKU 以适应租户的工作负载。

无论选择哪种隔离模型,都请确保验证租户数据即使在组件不可用或出现故障时也能保持适当的隔离。 考虑使用 Azure Chaos Studio 作为常规自动测试过程的一部分,以有意造成一些故障来模拟现实中断,同时验证解决方案是否不会在租户之间泄漏数据,并且即使在承压情况下也能保持正常运行。

要考虑的方法和模式

自动缩放

Azure 计算服务提供不同的功能来缩放工作负载。 许多计算服务支持自动缩放,你需要考虑何时应该缩放,以及所需的最小和最大缩放级别是什么。 可用于缩放的具体选项取决于使用的计算服务。 请参阅以下示例服务:

部署戳模式

有关如何使用部署缩放单元模式来支持多租户解决方案的详细信息,请参阅概述

计算资源合并模式

计算资源合并模式通过共享基础计算资源来帮助提高计算基础结构中的租户密度。 通过共享计算资源,通常可以降低这些资源的直接成本。 此外,管理成本通常更低,因为要管理的组件更少。

但是,计算资源合并会增大近邻干扰问题的可能性。 任何租户的工作负载都可能消耗不成比例的可用计算容量。 通常可以通过下述方式来缓解这种风险:确保适当缩放解决方案,并应用配额和 API 限制等控制措施来避免租户消耗超过其公平份额的容量。

可以根据使用的计算服务通过不同的方式实现此模式。 请参阅以下示例服务:

  • Azure 应用服务和 Azure Functions:部署表示宿主服务器基础结构的共享应用服务计划。
  • Azure 容器应用:部署共享环境
  • Azure Kubernetes 服务 (AKS):使用多租户感知的应用程序部署共享 pod。
  • 虚拟机:部署一组虚拟机供所有租户使用。

为每个租户部署专用计算资源

还可为每个租户部署专用计算资源。 专用资源可以确保每个租户的计算资源与其他租户的资源相隔离,从而缓解了近邻干扰问题的风险。 使用专用资源还能根据每个租户的要求为其资源部署不同的配置。 但是,专用资源通常会产生更高的成本,因为资源的租户密度更低。

需要根据使用的 Azure 计算服务部署不同的专用资源,如下所述:

  • Azure 应用服务和 Azure Functions:为每个租户部署单独的应用服务计划。
  • Azure 容器应用:为每个租户部署单独的环境。
  • Azure Kubernetes 服务 (AKS):为每个租户部署专用群集。
  • 虚拟机:为每个租户部署专用虚拟机。

半隔离计算资源

半隔离方法要求在隔离的配置中部署解决方案的各个方面,同时共享其他组件。

使用应用服务和 Azure Functions 时,可为每个租户部署不同的应用程序,并可以在共享的应用服务计划中托管应用程序。 此方法可以降低计算层的成本,因为应用服务计划代表计费单位。 它还使你能够将不同的配置和策略应用于每个应用程序。 但是,此方法会带来近邻干扰问题的风险。

使用 Azure 容器应用可将多个应用程序部署到共享环境,然后使用 Dapr 和其他工具来单独配置每个应用程序。

Azure Kubernetes 服务 (AKS) 和 Kubernetes 为多租户提供更多样化的选项,包括:

  • 特定于租户的命名空间,用于对部署到共享群集和节点池的特定于租户的资源进行逻辑隔离。
  • 共享群集上特定于租户的节点或节点池。
  • 可能使用同一节点池的特定于租户的 pod。

使用 AKS 还可应用 pod 级别的治理来缓解近邻干扰问题。 有关详细信息,请参阅有关管理 Azure Kubernetes 服务 (AKS) 中的资源的应用程序开发人员最佳做法

知道 Kubernetes 群集中的共享组件以及多租户如何影响这些组件也很重要。 例如,Kubernetes API 服务器是在整个群集中使用的共享服务。 即使提供特定于租户的节点池来隔离租户的应用程序工作负载,不同租户中的大量请求也可能会导致 API 服务器发生资源争用。

要避免的反模式

“近邻干扰”反模式

每当部署在租户之间共享的组件时,近邻干扰问题就是一个潜在风险。 确保包含资源治理和监视措施,以缓解租户的计算工作负载受到其他租户活动影响的风险。

跨租户数据漏泄

如果处理不当,计算层可能会受到跨租户数据泄漏的影响。 在 Azure 上使用多租户服务时,通常不需要考虑这一点,因为 Microsoft 在平台层提供了保护。 但是,当你开发自己的多租户应用程序时,请考虑任何共享资源(例如本地磁盘缓存、RAM 和外部缓存)是否包含其他租户可能无意中查看或修改的数据。

繁忙前端反模式

为避免出现繁忙前端反模式,请避免前端层执行大量的可能由体系结构的其他组件或层处理的任务。 为多租户解决方案创建共享前端时,此反模式尤其重要,因为繁忙前端会降级所有租户的体验。

请考虑通过利用队列或其他消息传递服务来改用异步处理。 使用此方法还可根据不同租户的要求对其应用服务质量 (QoS) 控制。 例如,所有租户可能共享一个公用前端层,但为更高服务级别付费的租户可能具有一组更高级别的专用资源用于处理其队列消息中的任务。

非弹性缩放或缩放不足

多租户解决方案往往受到突发缩放模式的影响。 共享组件特别容易受到此问题的影响,因为突发范围更广,当有更多租户具有不同的使用模式时,这种影响会进一步加大。

确保充分利用云的弹性和规模。 考虑是要使用水平缩放还是垂直缩放,并使用自动缩放来自动处理负载高峰。 测试解决方案以了解它在承受不同程度的负载情况下的行为。 确保包含的负载量与生产环境中的预期负载量和预期增长量相符。 可以使用完全托管的服务(例如 Azure 负载测试)来了解应用程序在承压情况下的行为方式。

无缓存反模式

无缓存反模式是指由于应用层反复请求或重新计算可在不同请求中重用的信息,而导致解决方案的性能受到影响。 如果你的数据可以在租户之间或者在单个租户中的用户之间共享,则可能最好是缓存这些数据,以降低后端/数据库层上的负载。

不必要的有状态性

根据无缓存反模式的影响得出的推论是,还应避免在计算层中存储不必要的状态。 明确说明保留状态的位置和原因。 有状态前端或应用层可能会降低缩放能力。 有状态计算层通常还需要会话亲和性,这会降低跨工作器或节点有效负载均衡流量的能力。

考虑保留在计算层中的每个状态片段带来的弊端,以及随着租户工作负载模式的变化,这些状态是否会影响缩放或扩充的能力。 还可将状态存储在 Azure Cache for Redis 等外部缓存中。

作者

本文由 Microsoft 维护, 它最初是由以下贡献者撰写的。

主要作者:

  • Dixit Arora | 高级客户工程师,FastTrack for Azure
  • John Downs | 首席软件工程师

其他参与者:

后续步骤

查看针对计算服务的特定服务指南: