第十八章 多租户架构设计 - 第二节:使用模式隔离或多租户扩展
文章目录
第二节 使用模式隔离或多租户扩展
目标:了解并评估“每个租户一个 Schema”的多租户隔离模型,并介绍像 TenantKit 这样的扩展如何简化这种模式的管理。
除了使用行级安全策略(RLS)在共享表中隔离数据外,另一种常见的多租户架构模式是为每个租户创建一个独立的 Schema。
“每个租户一个 Schema”模型
工作原理:
- 当一个新租户注册时,系统会自动地在数据库中创建一个以该租户的唯一标识(如
tenant_acme
,tenant_globex
)命名的 Schema。 - 所有属于该租户的表(
users
,products
等)都会被创建在这个专属的 Schema 内。 - 当一个用户登录并发起请求时,应用层会根据其租户身份,将数据库连接的**搜索路径(
search_path
)**设置为该租户的 Schema。
示例: 当来自 ‘acme’ 公司的 Alice 登录后,应用执行的第一个数据库命令是:
|
|
在此之后,所有不带 Schema 前缀的查询(如 SELECT * FROM products
)都会自动地、透明地指向 tenant_acme.products
这张表。由于 search_path
的限制,Alice 根本无法访问到 tenant_globex.products
。
优点与缺点
优点:
- 强隔离性:数据在逻辑上是完全隔离的,每个租户拥有自己的一套表。这提供了比 RLS 更直观、更强的安全感。
- 易于备份与恢复:可以非常容易地只备份或恢复单个租户的数据(
pg_dump -n tenant_acme
)。 - 租户级定制:可以为某个特定的大客户(租户)的 Schema 添加自定义的表、列或索引,而不会影响其他租户。
- 无查询开销:与 RLS 不同,这种模式在查询时没有额外的策略检查开销。
缺点:
- 管理复杂性:
- Schema 迁移:当需要对表结构进行变更(
ALTER TABLE
)时,你必须编写脚本来遍历所有租户的 Schema,并对其中的每一张表执行变更。这是一个非常复杂且容易出错的过程。 - 连接数问题:如果租户数量巨大(成千上万),数据库中会存在海量的表对象,这可能会给 PostgreSQL 的系统目录带来压力,并可能增加连接池和查询规划的开销。
- Schema 迁移:当需要对表结构进行变更(
- 跨租户查询困难:要进行跨所有租户的全局统计分析(例如,计算整个平台的总用户数),需要编写复杂的动态 SQL 来遍历所有
tenant_*
Schema 并用UNION ALL
将结果合并起来。
对比:RLS vs. Schema-per-Tenant
特性 | RLS (共享表) | Schema-per-Tenant |
---|---|---|
数据隔离级别 | 逻辑行级别 | 逻辑表/Schema级别 (更强) |
实现复杂度 | 中等 (需要定义 Policy) | 高 (需要管理 Schema 迁移) |
查询性能 | 有轻微开销 | 无开销 |
备份/恢复 | 较复杂 (需要过滤 tenant_id ) | 简单 |
Schema 变更 | 简单 (只需修改一次) | 非常复杂 |
跨租户分析 | 简单 | 非常复杂 |
适用租户规模 | 非常大 (数万甚至更多) | 中小规模 (几百到几千) |
选择建议:
- 如果你的应用租户数量可能非常巨大,并且跨租户的全局分析是一个核心需求,那么 RLS 方案通常更具扩展性和可维护性。
- 如果你的应用租户数量有限,每个租户的数据隔离性要求极高,并且需要为不同租户进行 Schema 定制,那么 Schema-per-Tenant 模型可能更合适。
使用扩展简化管理:TenantKit
手动管理成百上千个 Schema 的创建和迁移是一场噩梦。社区也为此提供了一些解决方案,例如 TenantKit。
TenantKit 是一个开源的 Ruby on Rails 引擎(或适用于其他框架的库),它旨在自动化 Schema-per-Tenant 模型的管理。
TenantKit 提供的功能:
- 租户创建/删除:当你在
tenants
表中创建一条新记录时,它会自动地创建对应的 Schema 和内部的表结构。 - 请求路由:根据请求的域名或子域名,自动地将数据库连接的
search_path
切换到正确的租户 Schema。 - 数据库迁移辅助:提供工具来帮助你在所有租户的 Schema 上统一执行数据库迁移脚本。
虽然 TenantKit 这样的工具极大地简化了开发工作,但它并不能完全消除 Schema-per-Tenant 模型固有的管理复杂性,特别是在处理失败的迁移和大规模集群时。
📌 小结
Schema-per-Tenant 是一种提供了极强逻辑隔离的多租户模型,它在租户级备份和定制方面具有明显优势。然而,这种优势是以极高的 Schema 管理复杂性为代价的。
在现代 SaaS 应用开发中,随着租户数量的快速增长和对敏捷迭代(快速变更表结构)的需求,RLS 方案因其更简单的维护模型和更好的扩展性,正变得越来越受欢迎。
在做架构选型时,你需要仔细评估业务的长期需求:是对物理隔离和租户级定制的需求更迫切,还是对平滑扩展和易于维护的需求更重要。