1. 可观测性工程导论

在传统数据平台里,运维团队习惯用“监控”来回答一个问题:系统现在是否正常。监控通常围绕已知故障模式设置阈值,例如CPU超过85%告警、任务失败重试三次告警。但AI数据平台面对的是另一类问题:模型输出为什么突然变差、某个特征在凌晨两点后为何漂移、一次RAG检索延迟升高究竟来自向量索引、嵌入模型还是网络。这些问题往往没有预先写好的阈值,需要从系统产生的海量信号中主动“问出来”。这就是可观测性工程与监控的分界线:监控回答“是否已知异常”,可观测性回答“为什么出现未知异常”。

在Databricks AI数据平台上,可观测性可以定义为:对Lakehouse中数据流、计算任务、模型服务与AI应用进行统一采集、关联和查询的能力,使工程师能够在不修改代码、不重启作业的前提下,从外部输出推断系统内部状态。这里的“外部输出”就是三大支柱——指标(Metrics)、日志(Logs)、追踪(Traces)。它们不是三套独立工具,而是同一事件在三个维度上的投影:指标是数值化的时间序列,日志是离散的文本事件,追踪是跨组件的因果链路。

核心判断:如果一个问题只能靠“加日志、重跑作业”才能定位,说明可观测性不足;如果通过已有指标、日志、追踪的关联查询就能定位,说明可观测性工程已经生效。

把三大支柱映射到Lakehouse架构,需要先看清数据平台的分层。典型Databricks Lakehouse从下到上包括:云存储与Delta Lake表、计算引擎(Spark/Photon)、作业调度(Workflows/Jobs)、数据管道(DLT/Lakeflow)、特征与模型资产(Feature Store/MLflow)、模型服务(Model Serving)、以及上层AI应用(RAG、Agent、BI)。每一层都产生不同形态的信号,而可观测性工程的任务就是让这些信号在同一个时间轴和同一个实体ID下可关联。

Lakehouse 分层与三大支柱映射 同一事件在指标、日志、追踪三个维度上的投影,通过 trace_id / job_id / table_id 关联 AI 应用层 RAG / Agent / BI / 推理API 模型服务层 Model Serving / 向量检索 特征与模型资产 Feature Store / MLflow 数据管道与调度 DLT / Workflows / Jobs 计算引擎 Spark / Photon / SQL Warehouse 存储与表格式 Delta Lake / Unity Catalog 指标 Metrics 数值 + 时间戳 + 标签 延迟 / 吞吐 / 错误率 / 成本 适合趋势与告警 日志 Logs 离散事件 + 上下文 异常堆栈 / 审计 / 数据质量 适合根因细节 追踪 Traces Span + 父子关系 + 耗时 跨服务调用链 / 检索链路 适合因果与瓶颈定位 关联键 trace_id job_id / run_id table_id / version model_name / version endpoint_name cluster_id user / workspace_id 统一时间轴 事件时间 vs 处理时间 统一存储 Delta 表 / 系统表 统一查询 SQL / Notebook / Dashboard 图1-1 Lakehouse 分层产生的信号分别落入指标、日志、追踪,并通过统一关联键在 Delta 表上完成联合查询

这张图想强调一个容易被忽略的事实:三大支柱不是按“工具”划分的,而是按“信号形态”划分的。同一个Spark作业失败,会产生三类信号——指标上表现为失败计数+1、日志上表现为ExecutorLostException堆栈、追踪上表现为某个stage的span异常结束。如果这三类信号没有共享job_id和run_id,工程师就只能分别在三个界面里手动对齐时间,定位效率会急剧下降。因此,可观测性工程的第一条实践原则是:在数据产生端就注入关联键,而不是在查询端做模糊匹配。

与传统数据平台相比,Databricks AI数据平台的可观测性有三个结构性差异。第一,数据本身也是被观测对象。传统平台监控作业是否成功,AI平台还要监控数据分布是否漂移、特征是否为空、训练集与推理集是否同分布。这些信号不是来自进程,而是来自表内容,需要用Delta表的历史版本做对比。第二,追踪的跨度从服务扩展到模型。一次RAG请求的trace不仅包含HTTP调用,还包含嵌入计算、向量检索、重排序、LLM生成四个阶段,每个阶段的耗时和token消耗都要能单独归因。第三,成本与质量必须同时可观测。传统平台关注CPU和存储成本,AI平台还要关注每次推理的token成本、向量索引的存储成本,以及模型输出质量随时间的衰减。

实践提示:在Databricks上落地可观测性,优先使用系统表(system tables)作为统一信号底座。system.billing.usage 提供成本,system.compute.node_timeline 提供计算资源,system.access.audit 提供操作审计,system.lakeflow.job_run_timeline 提供作业运行。它们天然带workspace_id和run_id,可以直接与业务表join,避免自建采集管道。

下面给出一个最小可用的关联查询示例,用于把一次模型服务调用的指标、日志、追踪对齐到同一个trace_id。假设已开启推理表的推理日志(inference table),并已配置MLflow tracing。

-- 示例:按 trace_id 关联推理日志与作业运行
WITH trace_events AS (
  SELECT
    request_id,
    trace_id,
    endpoint_name,
    model_version,
    latency_ms,
    input_tokens,
    output_tokens,
    status_code,
    event_time
  FROM ml.inference_logs.rag_endpoint_payload
  WHERE event_time >= current_timestamp() - INTERVAL 1 HOUR
)
SELECT
  t.trace_id,
  t.endpoint_name,
  t.model_version,
  t.latency_ms,
  t.input_tokens + t.output_tokens AS total_tokens,
  j.run_id,
  j.job_name,
  j.result_state
FROM trace_events t
LEFT JOIN system.lakeflow.job_run_timeline j
  ON t.trace_id = j.trace_id
WHERE t.status_code <> 200
ORDER BY t.latency_ms DESC
LIMIT 50;

这段查询的意图不是“跑通即可”,而是演示可观测性工程的核心动作:把服务侧信号(推理日志)与调度侧信号(作业运行)通过trace_id缝合。实际执行时,如果LEFT JOIN后run_id大量为NULL,说明追踪上下文没有从作业传递到服务,需要在服务调用处显式注入traceparent头;如果latency_ms的P99远高于P50,则应进一步下钻到追踪的span层级,看是向量检索慢还是LLM生成慢。判断依据是:P50正常而P99异常,通常是长尾请求或缓存未命中;P50和P99同时抬升,通常是下游依赖整体变慢。

需要特别说明的是,可观测性工程不是“把三个工具都装上”。它要求团队在架构设计阶段就回答三个问题:信号在哪里产生、关联键是什么、查询路径有多长。如果信号产生在服务内部但关联键只在网关层,那么跨层定位就会断裂;如果查询路径需要人工在三个系统间跳转,那么平均修复时间(MTTR)就不会真正下降。Databricks的优势在于Lakehouse本身可以作为可观测性数据的存储和查询层——指标、日志、追踪都可以落成Delta表,用SQL统一查询,用Unity Catalog统一治理权限。这意味着可观测性不再是独立于数据平台的旁路系统,而是数据平台的一部分。