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 和 tracestate HTTP 头传递 TraceID 与租户信息。
  • 自定义 Baggage: 在 OpenTelemetry Baggage 中携带 tenant_id,自动注入所有 Span 的 Attributes。
  • 服务网格注入: 在 Istio/Linkerd 层面通过 Envoy 拦截请求,自动添加租户标签到 Span。

3.4.2 多租户采样策略

链路追踪的数据量远大于指标,必须通过采样控制成本。多租户场景下推荐 自适应采样:

采样策略 适用场景 租户感知能力
固定概率采样 所有租户统一采样率 无
租户级采样 按租户设置不同采样率 强
头部采样 请求入口决定是否采样 中(需传递决策)
尾部采样 根据请求结果(如错误)决定 弱(需缓存全量 Span)

3.5 三大支柱的关联关系与多租户数据流

下图展示了在多租户架构中,Metrics、Logs、Traces 如何围绕一次用户请求协同工作,并通过 TraceID 实现数据关联:

多租户可观测性三大支柱关联数据流 用户请求(含 tenant_id) 服务 A(入口服务) Metrics(指标) tenant_id 标签 请求速率/延迟/错误率 Logs(日志) tenant_id + trace_id 字段 结构化事件记录 Traces(链路追踪) Span 链 + Baggage 租户上下文传播 TraceID 关联查询 通过 TraceID 关联 Metrics、Logs、Traces 租户隔离层(tenant_id 过滤 + 索引分区)

3.6 多租户场景下的核心挑战与设计原则

3.6.1 核心挑战

  • 数据隔离与共享的平衡: 完全隔离导致资源浪费,完全共享带来安全风险。
  • 标签/字段基数爆炸: 每个租户的独特标签组合可能导致存储索引膨胀。
  • 采样策略冲突: 高价值租户需要全量追踪,低成本租户只能接受采样。
  • 跨租户关联分析: 排查全局问题时需要跨越租户边界查询数据。

3.6.2 设计原则

原则 说明 实施建议
租户上下文前置注入 在数据采集入口即完成租户标识注入 使用 OpenTelemetry 的 Resource 或 Baggage
存储层按需隔离 根据租户 SLA 选择隔离级别 高 SLA 租户独立索引,低 SLA 租户共享索引
采样策略差异化 按租户等级配置采样率 头部采样 + 租户级采样率配置
关联键统一 三大支柱使用相同的 TraceID 和 tenant_id 标准化日志格式与 Span Attributes
核心总结: 在多租户可观测性系统中,Metrics 负责“是否异常”,Logs 负责“发生了什么”,Traces 负责“哪里出了问题”。三者通过统一的租户标识和 TraceID 形成闭环,缺一不可。