跳到主要内容

多租户隔离、配额与数据边界

多租户系统共享应用或基础设施,同时要在身份、数据、资源和运维操作上限制租户之间的影响。

1. 租户身份贯穿请求链路

系统首先要定义租户是什么:客户组织、内部团队、项目或独立工作负载。用户身份与租户身份需要分开,一个用户可能属于多个租户,并在每次请求中选择当前租户。

租户 ID 应来自经过验证的身份令牌或服务端会话,不能信任客户端任意提交的请求参数。网关、应用服务、异步消息、缓存键、数据库查询和审计日志都要携带同一租户上下文。

后台任务和系统管理员也需要显式租户范围。缺失租户上下文时默认拒绝,比默认访问全部租户更安全。

2. 选择共享与隔离模型

常见部署模型有三类:

  • Pool:多个租户共享应用和数据存储,通过租户字段隔离;
  • Silo:每个租户使用独立应用或存储;
  • Bridge:大部分租户共享,特定租户或组件使用独立资源。

Pool 的资源利用率和运维效率较高,数据越权与噪声邻居风险也更集中。Silo 提供更清楚的故障和数据边界,但部署数量、升级和成本都会增加。

选择依据包括合规要求、租户规模差异、性能保证、定制需求、服务限额和成本。一个产品可以让普通租户使用共享池,让高合规或大流量租户进入独立 stamp。

3. 授权同时检查用户与租户

通过身份认证后,还要确认用户在当前租户中的角色和资源权限。推荐的检查链是:

  1. 验证令牌签名、受众和有效期;
  2. 解析当前租户;
  3. 验证用户与租户的成员关系;
  4. 根据租户内角色和资源所有权授权;
  5. 记录主体、租户、资源和结果。

全局管理员能力单独建模,使用更强认证、最小权限和完整审计。不要用一个普通 isAdmin 字段隐式绕过所有租户过滤。

4. 数据访问默认带租户条件

共享表至少包含不可为空的 tenant_id,唯一约束和索引也要把租户维度纳入:

CREATE UNIQUE INDEX uk_order_no
ON orders (tenant_id, order_no);

应用可以在 Repository、ORM filter 或数据库行级安全中统一注入租户条件。关键是让遗漏条件尽可能在测试或运行时失败,不能依赖每位开发者手写 WHERE tenant_id = ?

缓存键、对象存储路径、搜索索引和消息 topic 同样需要租户边界。备份恢复、数据导出和删除请求要能准确选择单个租户,避免共享存储让合规操作无法落地。

5. 配额限制资源占用

资源隔离既包括硬上限,也包括拥塞时的公平调度。常见控制点包括:

  • 每租户请求速率与并发数;
  • 任务队列长度和消费者配额;
  • CPU、内存和网络限额;
  • 数据量、对象数量和保留期限;
  • 第三方 API 调用和费用预算。

全局限流只能保护系统总容量,无法阻止一个租户占满全部配额。按租户限流后,还需要为公共控制面和核心任务保留容量。

硬限额触发时返回明确错误和当前用量;弹性配额允许借用空闲容量时,要保证其他租户需要资源后能够收回。

6. 处理噪声邻居

噪声邻居不仅来自 CPU。慢 SQL、热点分区、大对象、连接池、消息积压和缓存淘汰都可能让一个租户影响其他租户。

排查需要按租户记录延迟、错误、资源、队列和数据库负载。治理可以分层进行:

  • 查询限时、并发舱壁和有界队列;
  • 按租户分区或分片;
  • 大租户迁移到独立资源;
  • 分级服务和优先级调度;
  • 对异常工作负载降速或暂停。

资源上限必须与产品套餐和业务预期一致,避免底层随意限流导致已承诺能力不可用。

7. 运维操作也要隔离

配置发布、数据库迁移和批处理可能同时影响所有租户。可以按 deployment stamp 或租户批次逐步发布,在小范围验证后扩大。

运维工具应支持租户范围预览、审批和审计。执行清理或回填前,先展示目标租户、数据量和预计影响;高风险操作提供 dry-run 和幂等重试。

监控至少能按租户和 stamp 切分。全局成功率正常时,大租户或某个区域仍可能已经完全不可用。

8. 成本归因支持容量决策

独立资源可以直接归属租户;共享资源需要按请求、计算时间、存储量、消息量或其他使用指标分摊。代理指标要与真实成本有稳定关系,并公开计算方式。

租户单位成本能帮助识别异常工作负载、定价缺口和隔离选择。成本归因不能替代安全隔离,但它能说明把某个租户移到独立资源是否合理。

9. 测试跨租户边界

除普通功能测试外,还要覆盖:

  • 租户 ID 缺失、伪造和切换;
  • 相同资源 ID 在不同租户出现;
  • 缓存、搜索和消息的跨租户读取;
  • 管理员越权和权限撤销;
  • 一个租户压满并发、存储和队列;
  • 单租户导出、删除、恢复和迁移。

生产前可以用两个结构相似的测试租户执行对抗测试:任何一侧都不能观察或影响另一侧的私有数据和配额。

10. 面试题

10.1 多租户系统怎样避免数据越权和单个租户占满资源

出现公司:网易严选

考察重点

  • 租户身份、授权和数据过滤的完整链路。
  • Pool、Silo 与混合隔离模型。
  • 按租户配额、噪声邻居和可观测性。

相关内容:第 1 节“租户身份贯穿请求链路”至第 9 节“测试跨租户边界”。

参考回答

我会让可信身份系统确定当前租户,并让租户上下文贯穿 HTTP、异步消息、缓存、数据库和审计。授权同时检查用户与租户关系,数据层统一注入租户条件,唯一索引、缓存键、对象路径和搜索索引都包含租户维度;缺失租户默认拒绝。

部署上根据合规、规模和成本选择共享池、独立 silo 或混合 stamp。资源保护按租户限制速率、并发、队列、存储和第三方费用,并按租户观测慢查询、热点和积压。异常大租户可以迁移到独立资源。最后专门测试 ID 伪造、缓存污染、相同资源 ID、管理员路径和单租户压测,验证数据与资源边界。