2. 多租户基础:SaaS多租户模型与Tenant ID设计
多租户(Multi-Tenancy)是SaaS架构的核心特征,指一个软件实例同时服务多个租户(Tenant),每个租户拥有独立的业务视图与数据边界。在可观测性系统中,多租户设计直接影响指标采集、日志路由、告警隔离与成本分摊的准确性。
2.1 SaaS多租户模型:隔离 vs 共享
根据租户间资源与数据的隔离程度,多租户模型分为三种主流模式。选择哪种模式取决于安全合规要求、运营成本与租户规模。
| 模型 | 数据隔离 | 计算资源 | 运维复杂度 | 典型场景 |
|---|---|---|---|---|
| 完全隔离(Database per Tenant) | 每个租户独立数据库 | 独立或共享 | 高(备份/迁移多) | 金融、医疗等强合规行业 |
| 共享数据库·独立Schema | 同一DB,不同Schema | 共享 | 中(Schema管理) | 中型SaaS,租户数100~1000 |
| 完全共享(Shared Table) | 同一表,Tenant ID区分 | 共享 | 低(资源利用率高) | 日志、指标等海量时序数据 |
可观测性场景建议: 指标与日志数据通常采用完全共享模型,利用Tenant ID实现逻辑隔离。这能最大化存储利用率,并支持跨租户的聚合查询。告警规则与配置数据则建议使用独立Schema,避免租户间的配置污染。
下图展示了三种模型在可观测性数据存储层的架构差异:
2.2 租户身份标识(Tenant ID)的设计原则
Tenant ID 是多租户系统的第一公民。在可观测性管道中,从数据采集、传输、存储到查询,Tenant ID 必须贯穿始终。设计不当会导致数据泄露、查询错误或性能瓶颈。
2.2.1 核心设计原则
- 全局唯一性:Tenant ID 必须在整个SaaS平台内唯一,避免跨租户数据混淆。推荐使用UUID v4或ULID。
- 不可变性:一旦分配,Tenant ID 不应变更。变更会导致历史数据与实时数据断裂,重建索引成本极高。
- 低熵可索引:Tenant ID 应适合作为数据库分区键或时序数据的Tag Key。避免使用过长字符串(如完整域名),推荐固定长度(如16字节)。
- 无业务含义:不要将租户名称、地域、等级编码进Tenant ID。业务变化会导致ID失效或歧义。
- 可排序(可选):对于时序数据库,按时间排序的ID(如ULID)能提升写入与查询局部性。
常见反模式: 使用自增整数作为Tenant ID。整数ID在合并数据库、跨区域同步或租户迁移时极易产生冲突,且无法满足分布式全局唯一要求。
2.2.2 Tenant ID 在可观测性数据中的嵌入方式
不同数据类型对Tenant ID的承载方式不同,下表总结了最佳实践:
| 数据类型 | 嵌入位置 | 示例 | 注意事项 |
|---|---|---|---|
| 指标(Metrics) | Label / Tag | http_requests_total{tenant="a1b2c3d4", ...} |
确保Tenant ID作为必选Label,不可省略 |
| 日志(Logs) | 结构化字段 | {"tenant_id": "a1b2c3d4", "message": "..."} |
建立索引,支持按租户快速过滤 |
| 链路追踪(Traces) | Span Attribute | span.SetAttributes("tenant.id", "a1b2c3d4") |
在入口Span注入,传播至子Span |
| 告警(Alerts) | 告警元数据 | alert.labels.tenant = "a1b2c3d4" |
用于告警路由与静默规则隔离 |
2.2.3 Tenant ID 在数据流中的传递路径
下图展示了Tenant ID从采集端到存储层的完整传递链路:
2.3 隔离与共享的权衡决策矩阵
在实际架构中,可观测性系统通常混合使用多种模型。以下决策矩阵帮助你在不同场景下做出选择:
| 决策维度 | 倾向隔离 | 倾向共享 |
|---|---|---|
| 安全合规等级 | 高(金融、医疗) | 低(内部工具、DevOps) |
| 租户数量 | 少(< 50) | 多(> 1000) |
| 数据量级 | 单租户TB级 | 海量小租户 |
| 跨租户查询需求 | 无 | 有(平台级聚合) |
| 运维人力 | 充足 | 有限 |
实战建议: 在可观测性系统中,推荐采用混合模型:指标与日志使用完全共享 + Tenant ID,告警规则与仪表盘配置使用独立Schema,而审计日志或敏感操作记录使用完全隔离。这样在成本、性能与安全之间取得最佳平衡。