1. 什么是多租户
多租户(Multi-Tenancy) 指用一套系统同时服务多个客户(租户),每个租户在逻辑上拥有独立、互不可见的数据与配置空间。
其本质是解决两个目标的平衡:
- 共享:共享得越多,资源成本与运维成本越低;
- 隔离:隔离得越彻底,数据安全风险越低、合规性越强。
与单租户系统的核心区别:单租户系统中“用户”已是最大隔离单位;多租户则是在用户之上再增加一层“租户”边界,要求满足:
- 租户之间互相看不到对方的数据与配置;
- 租户之间互不影响性能与资源用量;
- 租户可独立管理、独立审计、按需配额。
2. 运行原理:三个核心机制
多租户在运行期的实现原理可以拆解为三个机制:租户识别 → 租户上下文 → 数据路由。
flowchart LR
A["客户端请求<br/>携带租户标识<br/>(子域名 / Token / 请求头)"] --> B["网关 / 中间件<br/>识别并校验租户<br/>(整个请求仅识别一次)"]
B --> C["建立租户上下文<br/>tenant_id 贯穿全链路"]
C --> D["应用层处理<br/>权限·配置·功能开关<br/>按租户加载"]
D --> E["数据层路由<br/>按隔离级别读写数据"]
C -.-> F["缓存 / 文件存储 / 消息队列<br/>同样必须携带租户上下文"]
2.1 租户识别
系统如何判断请求来自哪个租户?常见的三种标识来源:
| 标识方式 | 说明 | 特点 |
|---|---|---|
| 独立子域名 | 如 tenantA.example.com |
直观,适合 SaaS 对外场景 |
| 登录凭证声明 | 认证 Token 中携带租户信息 | 与统一认证体系天然结合 |
| 请求头 / 账号体系 | 登录后由账号归属决定 | 适合集团内部多组织场景 |
识别动作发生在链路最外层(网关 / 中间件),整个请求只识别一次,不要求业务代码反复判断。
2.2 租户上下文
识别完成后,将租户标识放入一个随请求传递的上下文对象。后续所有环节——权限校验、配置读取、缓存取用、数据访问——都自动携带租户身份,业务逻辑无需手工逐层传参。
改造工作量的大头在这里:多租户改造的本质,是把原系统“只有用户维度”的处理链路,升级为“用户 + 租户”双维度链路。
2.3 数据路由
请求到达数据层时,按系统选定的隔离级别,把读写操作导向对应的数据单元——同一张表、同一个库的不同 Schema、不同的数据库,或完全独立的应用实例。隔离层级的选择见下一章。
3. 数据隔离的四种层级
多租户最关键的架构分叉点:租户的数据在哪一层切开。共有四种常见层级:
flowchart TB
subgraph L1["① 字段级 · 共享表"]
DB1[("共享数据库")] --> T1["业务表<br/>以 tenant_id 列区分租户<br/>所有租户数据混存"]
end
subgraph L2["② Schema 级"]
DB2[("共享数据库")] --> S1["Schema:租户A"]
DB2 --> S2["Schema:租户B"]
DB2 --> S3["Schema:租户C"]
end
subgraph L3["③ 库级"]
DB3[("数据库实例")] --> DA[("租户A库")]
DB3 --> DBb[("租户B库")]
end
subgraph L4["④ 实例级 · 物理隔离"]
P["统一门户 / 统一认证"] --> IA["应用实例A + 独立库A"]
P --> IB["应用实例B + 独立库B"]
end
3.1 四种层级对比
| 层级 | 数据怎么放 | 靠什么保证隔离 | 主要代价 | 典型场景 |
|---|---|---|---|---|
| ① 字段级(共享表) | 所有租户数据混在同一张表,以 tenant_id 列区分 | 应用层:每条查询自动注入租户过滤条件 | 漏一条过滤即串数据;查询必须命中租户前缀索引;大租户拖慢全体租户 | 租户数量多、单租户数据量小、SaaS 化产品 |
| ② Schema 级 | 同一个数据库,每个租户一套独立表结构 | 数据库结构边界 + 连接按租户切换 | 表结构升级要执行 N 遍;Schema 数量存在上限 | 租户几十到几百、隔离要求中等 |
| ③ 库级 | 同实例分库,或独立数据库 | 库边界天然隔离 | 资源占用升高;跨租户统计与聚合困难 | 隔离要求中高、单租户数据量大 |
| ④ 实例级(物理隔离) | 整套应用 + 数据库独立部署,前端挂统一门户 | 基础设施物理边界 | 服务器与运维成本最高,但对存量系统改造量最小 | 强合规、大客户、存量单租户产品多租户化 |
3.2 关键理解
隔离级别越低,隔离越靠“工程纪律”保证;隔离级别越高,越靠“基础设施”保证。
- ① 字段级方案的风险从来不在架构设计,而在每一条查询都不能遗漏租户条件——这是多数团队实施多租户翻车的地方;
- ④ 实例级方案的隔离由部署拓扑天然保证,几乎不存在“串数据”风险,代价是资源与运维成本;
- ②③ 位于中间,用数据库的结构/实例边界换取部署密度。
4. 数据之外的隔离要点
数据表之外,以下四个环节同样必须携带租户上下文,是方案评审中最容易被忽略、实施期最容易翻车的位置:
| 环节 | 隔离要求 | 典型事故 |
|---|---|---|
| 缓存 | 缓存 Key 必须携带租户前缀 | 租户 A 的数据被缓存命中后返回给租户 B |
| 文件 / 对象存储 | 按租户分目录或分桶,访问路径做租户校验 | 文件 URL 被跨租户遍历访问 |
| 异步任务 / 消息队列 | 消息体携带租户上下文,消费者侧还原上下文 | 定时任务/批量处理时租户边界丢失 |
| 配置与功能开关 | 租户级配置独立存储,而非全局配置 | 修改租户 A 的开关影响到所有租户 |
5. 租户管理与权限体系
多租户不只是数据隔离,还需要配套的管理体系:
flowchart TB
T["租户<br/>(独立数据与配置空间)"] --> TA["租户管理员"]
T --> O["组织 / 部门"]
O --> U["用户"]
T --> R["角色 / 权限集"]
U -- 归属 --> R
TA -- "管理本租户内的<br/>组织·用户·权限·配额" --> O
配套能力包括:
- 租户生命周期管理:租户开通、冻结、注销、数据导出与清除;
- 分级管理员:租户管理员管理本租户内部的组织、用户与权限,平台方不介入租户内部事务;
- 配额与计量:按租户限制存储量、用户数、调用量等资源,支撑计费或内部成本分摊;
- 租户级审计:操作日志、登录日志按租户维度归档与检索。
6. 技术选型决策
flowchart TD
S["多租户选型决策"] --> Q1{"合规 / 监管是否要求<br/>物理级隔离?"}
Q1 -- 是 --> L4["④ 实例级 · 物理隔离<br/>统一门户 + 独立部署"]
Q1 -- 否 --> Q2{"租户数量规模?"}
Q2 -- "少(几个 ~ 几十个)" --> Q3{"单租户数据量大?"}
Q3 -- 是 --> L3["③ 库级隔离"]
Q3 -- 否 --> L2["② Schema 级隔离"]
Q2 -- "多(成百上千)" --> L1["① 字段级 · 共享表<br/>tenant_id 逻辑隔离"]
选型输入变量归结为三个:
- 合规要求——是否强制物理隔离(一票否决项);
- 租户数量与增长预期——决定共享度可以做到多高;
- 单租户数据量与并发——决定是否需要独立的资源边界(防“噪声邻居”)。
补充两条工程经验:
- 存量单租户产品做多租户,首选 ④ 实例级(统一门户 + 独立部署)过渡:改造量最小、隔离最强,且对客户最容易讲清楚;
- ① 字段级方案是唯一能支撑大规模 SaaS 的路线,但必须同步建设自动化的租户条件注入与测试防线。
7. 实施风险与注意事项
| 风险点 | 说明 | 应对 |
|---|---|---|
| 存量数据迁移 | 老数据补写租户归属、迁移期间双写一致性问题 | 迁移方案单独立项评估,预留灰度与回滚窗口 |
| 租户级备份恢复 | 共享架构下“只恢复某一个租户”困难 | 库级/Schema 级天然支持;共享表方案需设计数据级恢复手段 |
| 噪声邻居 | 大租户的高负载拖慢共享资源上的其他租户 | 租户级限流、配额,必要时升降级隔离层级 |
| 工程纪律(①方案) | 任一查询遗漏租户条件即数据串写 | 数据访问层统一注入 + 上线前自动化扫描兜底 |
| 结构升级成本(②方案) | 每次表结构变更需在 N 个 Schema 上执行 | 变更脚本化、批量化,纳入发布流水线 |
8. 演进路线建议
多租户能力通常不一步到位,建议按三阶段演进:
flowchart LR
P1["阶段一<br/>实例级隔离"] --> P2["阶段二<br/>逻辑多租户"] --> P3["阶段三<br/>平台化 / SaaS 化"]
| 阶段 | 目标 | 关键动作 | 特点 |
|---|---|---|---|
| 一:实例级隔离 | 快速满足多租户“体感” | 统一门户、统一认证,租户独立部署 | 基于现有架构即可交付,隔离最强 |
| 二:逻辑多租户 | 降低资源与运维成本 | 数据层租户化改造、缓存/文件/队列隔离、租户管理后台 | 架构级变更,需独立评估工作量 |
| 三:平台化 / SaaS 化 | 支撑规模化运营 | 租户自助开通、配额计费、运营报表 | 产品级能力,按产品规划推进 |
附:一页速览
- 多租户 = 一套系统服务 N 个租户,核心是共享与隔离的平衡;
- 运行原理三机制:租户识别 → 租户上下文 → 数据路由,上下文贯穿全链路是改造重点;
- 数据隔离四层级:字段级 < Schema 级 < 库级 < 实例级,隔离越强成本越高、对存量系统改造越小;
- 级别越低越靠工程纪律,级别越高越靠基础设施;
- 缓存、文件、异步任务、配置四处同样要带租户上下文;
- 选型三输入:合规要求、租户规模、单租户数据量;
- 演进路线:实例级 → 逻辑多租户 → 平台化。