2. Databricks Lakehouse实时能力全景

在 Databricks Lakehouse 中谈“实时”,并不是某一个组件单独完成的,而是五个核心能力在一条链路上各司其职、彼此衔接:Delta Lake 负责把数据落成可增量读写、可回溯的表;Structured Streaming 负责把连续到达的数据按微批或连续模式持续处理;Photon 负责把执行引擎的算力真正提上去;Unity Catalog 负责让这些表、流、权限和血缘在统一治理下可管可控;DLT(Delta Live Tables) 则把“流式管道”从手写作业提升为声明式、可观测、可依赖编排的数据产品。理解它们的定位,比记住它们各自的功能更重要。

一、五个组件在实时链路中的位置

可以把一条典型的实时链路拆成“接入—处理—存储—治理—编排”五个层面。Delta Lake 是存储层的事实标准,它让一张表既能被批处理读取,也能被流式增量读取,还能支持 MERGE、UPDATE、时间旅行和 OPTIMIZE。Structured Streaming 是计算层的流式 API,它把 Kafka、Kinesis、Auto Loader 等源抽象成“无界表”,让开发者用类似批处理的方式写流逻辑。Photon 是执行层的向量化引擎,它不改变 API,但会显著改变扫描、聚合、连接等算子的执行效率。Unity Catalog 是治理层,它统一管理 catalog、schema、table、volume、function 以及权限和血缘。DLT 是编排层,它用 @dlt.table 声明数据集,用 @dlt.expect 声明质量约束,由运行时自动构建依赖 DAG、管理检查点、重试和监控。

Databricks Lakehouse 实时链路五层协作全景 数据接入 Kafka / Kinesis Auto Loader / Event Hub Structured Streaming 无界表抽象 · 微批/连续 watermark · checkpoint Photon 引擎 向量化执行 扫描/聚合/连接加速 Delta Lake ACID · 时间旅行 MERGE · OPTIMIZE Unity Catalog 统一治理层 catalog / schema / table / volume / function · 权限 · 血缘 · 审计 · 跨工作区共享 DLT(Delta Live Tables)声明式编排层 @dlt.table 声明数据集 · @dlt.expect 质量约束 · 自动依赖 DAG · 检查点与重试 · 事件日志 流式表 / 物化视图 / 流式物化视图 统一编排 协作关系要点: ① Structured Streaming 读写 Delta 表,Delta 提供增量源与 ACID 落点;② Photon 在流式与批式执行中透明加速; ③ Unity Catalog 统一管控所有表与流对象;④ DLT 把上述能力封装为可声明、可观测、可依赖编排的实时管道。

二、Delta Lake:实时链路的“可增量存储底座”

实时链路最怕的不是算得慢,而是“算完了不知道写到哪里、写坏了没法回退”。Delta Lake 解决的就是这个问题。它在 Parquet 之上维护一份事务日志 _delta_log,每次写入生成一个新的 JSON 提交文件,记录新增/删除的文件、schema 变化和统计信息。读取时先读日志再读数据文件,因此天然支持快照隔离和 ACID。

对实时场景最关键的两个能力是:增量读取和幂等写入。增量读取让下游流可以只消费“上次之后新增的数据”,而不必全表扫描;幂等写入则通过 MERGE INTO 按主键更新,避免重复消费导致的数据重复。例如,一张订单实时表可以这样维护:

MERGE INTO silver_orders AS t
USING staging_orders AS s
ON t.order_id = s.order_id
WHEN MATCHED AND s.updated_at > t.updated_at THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;

这段逻辑在 Structured Streaming 的 foreachBatch 中执行,就能实现“流式接入、按主键去重更新”的效果。Delta 还提供 OPTIMIZE 合并小文件、Z-ORDER 提升多维过滤效率,以及 VACUUM 清理旧版本。实时表如果长期高频写入,小文件问题会迅速累积,因此通常需要配合定时 OPTIMIZE 或使用 DLT 的自动优化能力。

三、Structured Streaming:把“无界数据”当成表来处理

Structured Streaming 的核心思想是:把流式数据源看作一张不断追加的表,用户写的查询和批处理查询几乎一样,引擎负责把它增量执行。它支持 append、update、complete 三种输出模式,并通过 checkpointLocation 记录已处理偏移量,保证故障恢复后不丢不重。

在实时链路中,它通常承担“接入—清洗—聚合—写出”的连续处理。一个典型配置如下:

spark.readStream
  .format("kafka")
  .option("kafka.bootstrap.servers", "broker:9092")
  .option("subscribe", "orders")
  .option("startingOffsets", "latest")
  .load()
  .selectExpr("CAST(value AS STRING) AS json")
  .writeStream
  .option("checkpointLocation", "/checkpoints/orders")
  .trigger(processingTime="30 seconds")
  .toTable("bronze_orders");

这里 trigger 决定微批节奏,checkpointLocation 决定容错边界。对于有迟到数据的场景,还需要设置 withWatermark,让引擎知道“多久之后的数据可以不再等待”,从而控制状态大小。Structured Streaming 本身不负责存储,它把结果写到 Delta 表、Kafka 或外部系统,因此它与 Delta Lake 是天然的搭档。

四、Photon:不改变 API 的执行加速层

Photon 是 Databricks 用 C++ 重写的向量化查询引擎,它运行在 Photon 集群上,对 SQL、DataFrame 和 Structured Streaming 中的扫描、过滤、聚合、连接等算子进行加速。它的价值在于:用户不需要改代码,只要把作业跑在 Photon 集群上,就能获得更高的吞吐和更低的单次查询延迟。

在实时链路中,Photon 的意义是让“微批”跑得更快。假设一个 30 秒触发一次的微批需要处理 200 万条记录,如果单批执行时间从 25 秒降到 12 秒,那么留给突发流量的余量就更大,端到端延迟也更稳定。需要注意的是,Photon 不是所有算子都覆盖,某些自定义 UDF 或复杂 Python 逻辑仍会回退到 JVM 执行,因此实际收益要看算子构成。

五、Unity Catalog:让实时资产“可管、可查、可授权”

实时链路一旦上线,表、流、检查点、权限和血缘会迅速增多。Unity Catalog 提供三层命名空间 catalog.schema.table,把表、视图、卷、函数统一纳管,并支持细粒度权限(SELECT、MODIFY、USE SCHEMA 等)和自动血缘采集。对实时场景,它解决三个实际问题:

  • 权限一致:流式作业读写 Delta 表时,权限由 Unity Catalog 统一校验,避免每个作业单独配 ACL。
  • 血缘可见:从 Kafka 接入到 silver、gold 表的加工路径可以被自动记录,排障时能快速定位上游。
  • 跨工作区共享:实时表可以被多个工作区、多个团队按授权访问,而不需要复制数据。

因此,在部署实时链路时,建议一开始就用 Unity Catalog 管理所有目标表,而不是先建外部表再迁移。

六、DLT:把实时管道变成“声明式数据产品”

DLT 是这五个组件里最“上层”的一个。它不替代 Structured Streaming,而是把流式管道的构建、依赖、质量约束和监控封装成声明式 API。开发者只需定义数据集和期望,DLT 运行时自动决定执行顺序、管理检查点、处理重试,并把每次运行的事件写入事件日志。

@dlt.table(name="bronze_orders")
def bronze_orders():
    return (spark.readStream.format("kafka")
            .option("subscribe", "orders").load())

@dlt.table(name="silver_orders")
@dlt.expect_or_drop("valid_amount", "amount > 0")
def silver_orders():
    return dlt.read_stream("bronze_orders").select("order_id", "amount")

这段代码里,@dlt.table 声明数据集,@dlt.expect_or_drop 声明质量规则,DLT 会自动构建 bronze→silver 的依赖关系,并在每次更新时记录指标。相比手写 Structured Streaming 作业,DLT 的优势在于:依赖关系显式化、质量约束内建、监控开箱即用、支持流式表与物化视图混合编排。

七、协作关系:一条实时链路的完整视角

把五个组件串起来看:数据从 Kafka 进入,由 Structured Streaming 读取;读取过程中 Photon 加速算子执行;处理结果写入 Delta Lake 表;这些表由 Unity Catalog 统一治理;而整条管道由 DLT 声明式编排。它们不是替代关系,而是分层协作关系。实际部署时,常见的组合是:DLT + Structured Streaming + Delta Lake + Unity Catalog + Photon 集群,其中 DLT 负责编排,Structured Streaming 负责流语义,Delta 负责存储,Unity Catalog 负责治理,Photon 负责加速。

判断一个实时方案是否用对了这些组件,可以问四个问题:数据落点是不是 Delta 表?流处理是否用了 checkpoint 和 watermark?表是否纳入了 Unity Catalog?管道是否用 DLT 声明了依赖和质量约束?四个都满足,链路的基本盘就稳了。