3. 可观测性三大支柱:Metrics、Logs、Traces 在多租户场景下的基础概念
在多租户可观测性系统中,Metrics(指标)、Logs(日志)、Traces(链路追踪) 构成了数据采集与分析的三大支柱。理解它们在多租户环境下的基础概念与边界差异,是设计隔离策略与优化数据传输的前提。
3.1 三大支柱的核心定义与数据特征
三大支柱各自承载不同类型的可观测性数据,其采集频率、存储模型与查询模式存在本质区别。下表从多租户视角对比了它们的关键特征:
| 维度 | Metrics(指标) | Logs(日志) | Traces(链路追踪) |
|---|---|---|---|
| 数据本质 | 时间序列聚合值 | 离散事件文本记录 | 请求链路结构化数据 |
| 典型粒度 | 秒/分钟级聚合 | 单行事件 | 单次请求 Span 链 |
| 存储模型 | 时序数据库(TSDB) | 全文索引/日志存储 | 图/关系型存储 |
| 租户隔离粒度 | Label/Tag 维度 | 索引字段/元数据 | Span Tag/Service Name |
| 数据量级 | 低(固定采集周期) | 高(随业务量线性增长) | 中(采样率可控) |
| 查询模式 | 范围聚合 + 降采样 | 关键词搜索 + 过滤 | TraceID 关联 + 拓扑分析 |
关键认知: 三大支柱并非互斥,而是互补关系。在多租户场景中,TraceID 是串联 Metrics、Logs 与 Traces 的核心关联键,也是实现跨租户数据隔离与关联分析的基础。
3.2 Metrics(指标):多租户下的聚合与维度隔离
指标是经过聚合的数值型时间序列数据,通常由 Metric Name + Labels/Tags 唯一标识。在多租户架构中,租户信息必须作为标签注入指标流。
3.2.1 租户标签注入策略
- 全局标签注入: 在采集器(如 Prometheus Agent、Telegraf)层面统一添加
tenant_id标签,确保所有指标携带租户上下文。 - 服务端标签映射: 在指标存储层(如 Thanos、VictoriaMetrics)通过 Relabeling 规则从服务名或命名空间推导租户归属。
- 多租户命名空间: 使用独立的 Metric Prefix 或 Namespace 区分租户,例如
tenant_a_http_requests_total。
3.2.2 典型多租户指标示例
# 带租户标签的 Prometheus 指标
http_requests_total{tenant_id="tenant_a", service="payment", status="200"} 1024
http_requests_total{tenant_id="tenant_b", service="payment", status="200"} 512
# 查询时按租户过滤
sum by (tenant_id) (http_requests_total{status="200"})
避坑提示: 高基数标签(如
user_id、request_id)不应直接作为指标标签,否则会导致时序数据库性能急剧下降。租户隔离应使用有限基数的 tenant_id 或 namespace。
3.3 Logs(日志):多租户下的结构化与索引隔离
日志是离散的、非结构化的文本事件记录。在多租户场景中,日志的租户隔离主要依赖 索引/表分区 与 元数据字段 两种方式。
3.3.1 日志租户隔离模式对比
| 隔离模式 | 实现方式 | 优势 | 劣势 |
|---|---|---|---|
| 索引隔离 | 每个租户独立索引/表 | 数据完全隔离,查询互不影响 | 索引数量膨胀,运维成本高 |
| 字段隔离 | 共享索引,通过 tenant_id 字段过滤 |
资源利用率高,管理简单 | 查询需全索引扫描,性能受限于过滤效率 |
| 分区隔离 | 按租户 ID 进行时间分区 | 兼顾隔离性与查询性能 | 分区策略需提前规划 |
3.3.2 结构化日志推荐格式
{
"timestamp": "2025-03-21T10:00:00.123Z",
"tenant_id": "tenant_a",
"service": "order-service",
"level": "ERROR",
"trace_id": "abc123def456",
"message": "订单支付超时",
"metadata": {
"order_id": "ORD-20250321-001",
"amount": 99.99
}
}
最佳实践: 始终在日志中携带
tenant_id 和 trace_id。前者用于租户隔离过滤,后者用于与链路追踪关联。推荐使用 JSON 结构化格式,便于日志系统自动解析索引。
3.4 Traces(链路追踪):多租户下的上下文传播与采样
链路追踪记录一次请求在分布式系统中的完整调用路径,核心数据结构为 Span。在多租户场景中,租户上下文必须在请求链路的起点注入,并随 Context Propagation 机制传递到所有下游服务。
3.4.1 租户上下文传播机制
- W3C Trace Context: 通过
traceparent和tracestateHTTP 头传递 TraceID 与租户信息。 - 自定义 Baggage: 在 OpenTelemetry Baggage 中携带
tenant_id,自动注入所有 Span 的 Attributes。 - 服务网格注入: 在 Istio/Linkerd 层面通过 Envoy 拦截请求,自动添加租户标签到 Span。
3.4.2 多租户采样策略
链路追踪的数据量远大于指标,必须通过采样控制成本。多租户场景下推荐 自适应采样:
| 采样策略 | 适用场景 | 租户感知能力 |
|---|---|---|
| 固定概率采样 | 所有租户统一采样率 | 无 |
| 租户级采样 | 按租户设置不同采样率 | 强 |
| 头部采样 | 请求入口决定是否采样 | 中(需传递决策) |
| 尾部采样 | 根据请求结果(如错误)决定 | 弱(需缓存全量 Span) |
3.5 三大支柱的关联关系与多租户数据流
下图展示了在多租户架构中,Metrics、Logs、Traces 如何围绕一次用户请求协同工作,并通过 TraceID 实现数据关联:
3.6 多租户场景下的核心挑战与设计原则
3.6.1 核心挑战
- 数据隔离与共享的平衡: 完全隔离导致资源浪费,完全共享带来安全风险。
- 标签/字段基数爆炸: 每个租户的独特标签组合可能导致存储索引膨胀。
- 采样策略冲突: 高价值租户需要全量追踪,低成本租户只能接受采样。
- 跨租户关联分析: 排查全局问题时需要跨越租户边界查询数据。
3.6.2 设计原则
| 原则 | 说明 | 实施建议 |
|---|---|---|
| 租户上下文前置注入 | 在数据采集入口即完成租户标识注入 | 使用 OpenTelemetry 的 Resource 或 Baggage |
| 存储层按需隔离 | 根据租户 SLA 选择隔离级别 | 高 SLA 租户独立索引,低 SLA 租户共享索引 |
| 采样策略差异化 | 按租户等级配置采样率 | 头部采样 + 租户级采样率配置 |
| 关联键统一 | 三大支柱使用相同的 TraceID 和 tenant_id | 标准化日志格式与 Span Attributes |
核心总结: 在多租户可观测性系统中,Metrics 负责“是否异常”,Logs 负责“发生了什么”,Traces 负责“哪里出了问题”。三者通过统一的租户标识和 TraceID 形成闭环,缺一不可。