4、多租户架构模式:SaaS多租户模型、数据隔离 vs 计算隔离、共享与独享策略

多租户(Multi-Tenancy)是 SaaS 架构的核心特征,指一套软件实例同时服务多个租户(客户/组织)。在可观测性平台中,多租户设计直接决定了数据隐私、资源配额、计费模型和运维复杂度。本章从 SaaS 多租户模型出发,深入分析数据隔离与计算隔离的权衡,并给出共享与独享策略的选型指南。

4.1 SaaS 多租户模型

根据租户间资源共享程度,SaaS 多租户通常分为三种模型:

模型 描述 典型场景 隔离强度
独立实例(Single-Tenant) 每个租户拥有独立的数据库、计算资源和应用进程 金融、医疗等强合规行业 最高
共享实例(Shared-Tenant) 所有租户共享同一套应用和数据库,通过租户 ID 逻辑隔离 中小型 SaaS、日志/指标聚合平台 中等
混合模型(Hybrid) 部分资源共享(如计算层),部分资源独享(如存储层) 大型可观测性平台(如 Datadog、Grafana Cloud) 可配置
可观测性场景提示: 日志、指标、链路追踪的数据量通常随租户规模呈指数增长。纯共享实例在数据量超过 PB 级时,查询性能会因“吵闹邻居”效应急剧下降,因此大型平台几乎都采用混合模型。

4.2 数据隔离 vs 计算隔离

在多租户架构中,数据隔离和计算隔离是两个独立但相互关联的维度。下表对比了二者的核心差异:

维度 数据隔离 计算隔离
关注点 租户 A 不能读取租户 B 的数据 租户 A 的查询/写入不抢占租户 B 的 CPU/内存
实现方式 行级权限、Schema 分离、独立数据库、加密密钥分离 容器 cgroup、K8s ResourceQuota、独立进程/节点
失败影响 数据泄露、合规违规 性能抖动、SLA 违约
可观测性侧重点 审计日志、数据访问控制(DAC) 资源使用率、限流/降级指标

在 Docker 容器化环境中,计算隔离通常通过 cgroup v2 的 CPU/内存限制和 Docker 资源约束(--cpus、--memory)实现;数据隔离则依赖存储后端(如 ClickHouse、Elasticsearch)的租户路由机制。

常见误区: 很多团队认为“只要用了容器,计算就自动隔离了”。实际上,默认情况下 Docker 容器共享宿主机内核和 CPU 时间片,如果没有显式设置资源限制,一个租户的突发流量仍可能耗尽所有计算资源,导致其他租户的查询超时。

4.3 共享与独享策略

在可观测性平台中,不同组件对共享/独享的敏感度不同。以下策略矩阵帮助架构师做出权衡:

组件 推荐策略 理由
数据采集 Agent 独享(每个租户独立 Agent 进程) 避免租户间数据混淆,便于独立升级和故障隔离
消息队列(Kafka) 共享 Topic + 分区隔离 降低运维成本,通过分区数控制租户吞吐量
存储引擎(OLAP) 混合:共享集群 + 独立表/分片 平衡存储利用率与查询隔离,支持按租户设置 TTL
查询网关(API) 共享 + 限流 统一入口,通过令牌桶或并发限制实现租户级 QoS
告警引擎 独享(独立评估进程) 告警规则评估是 CPU 密集型,避免相互阻塞导致告警延迟

4.4 多租户隔离架构总览

下图展示了一个典型的可观测性平台多租户隔离架构,涵盖数据流、计算隔离边界和共享/独享决策点:

多租户隔离架构总览 可观测性平台多租户隔离架构 租户 A(独享 Agent) 租户 B(独享 Agent) 共享基础设施层 采集 Agent(独享) 采集 Agent(独享) Kafka(共享 Topic) 流式计算(共享 + cgroup) OLAP 存储(共享集群) 告警引擎(独享) 告警引擎(独享) 查询网关(共享 + 限流) 说明:Agent 和告警引擎采用独享策略;消息队列、流式计算、存储和查询网关采用共享策略,并通过 cgroup/限流实现计算隔离

4.5 共享与独享策略的选型决策树

在实际架构设计中,可以按以下决策树快速判断某个组件应采用共享还是独享策略:

  1. 该组件是否涉及租户敏感数据?
    • 是 → 优先考虑独享或强数据隔离(如独立表/独立进程)
    • 否 → 进入下一步
  2. 该组件是否是 CPU/IO 密集型?
    • 是 → 评估是否可接受“吵闹邻居”效应;若不可接受,选择独享
    • 否 → 进入下一步
  3. 该组件的运维成本是否随租户数量线性增长?
    • 是 → 优先共享,通过限流和资源配额实现隔离
    • 否 → 独享更简单,故障域更小
  4. 是否有明确的 SLA 要求?
    • 是 → 独享或混合模式,确保资源预留
    • 否 → 共享模式,降低成本
实践建议: 在可观测性平台初期,建议采用“共享计算 + 独享存储”的混合模式。计算层通过 Docker 的 --cpus 和 --memory 限制每个租户的资源上限;存储层使用 ClickHouse 的 ALTER TABLE ... MODIFY TTL 按租户设置数据生命周期,同时利用 Row Policy 实现行级数据隔离。这样既能控制成本,又能满足大多数场景的隔离需求。