现代数据工程生态的层级地图
过去十年数据栈最大的变化是 “Hadoop 时代的大一统散架了”:原来一个 Hadoop 生态打包了存储、计算、调度、查询,现在每一层都裂出了独立的明星项目。今天搭一套生产级数据平台,你会同时听到 Debezium、Kafka、Airbyte、Spark、Flink、dbt、Iceberg、ClickHouse、Trino、Redis、Superset、Metabase、Airflow、DataHub 这一长串名字 — 它们对应的是 同一张分层架构图上不同的格子。
这篇文章按 数据源 → 数据集成 → 计算处理 → 存储 → 查询服务 → 应用层 六层组织,再加上贯穿全栈的 编排 与 治理 两条横切。每个项目按四段式展开:发展过程 / 核心设计 / 用户情况 / Demo 代码。Demo 不追求可运行的完整工程,只取能表达每个工具”灵魂”的最小片段 — 看完这一篇,你应该能回答两个问题:这个工具凭什么活在这一层,以及 要写最简单的一行代码,长什么样。
概览 — 六层分工 · 一张架构图
先把整张图摊开。下图是这篇文章的骨架 — 六个水平层从上到下,每层挑出最主流的 1-2 个代表项目;左侧的 Airflow 竖向贯穿,因为调度是个”对所有计算节点都生效”的横切关注;底部的 Catalog 是另一条横切 — 所有存储里”数据是什么”的事实,都登记在元数据 catalog 里。
这套图有几个值得先点出来的事实:
- 第三层”计算”和第五层”查询”出现重复的项目(Spark / Spark SQL,Flink / Flink SQL):这是因为现代分布式引擎都是”计算 + 查询”双身份 — 同一个 jar、同一个 cluster,既可以跑离线 ETL,也可以接受交互式 SQL 请求。
- 第四层不是一个 box,而是两个并列的 hub — 湖仓 (S3 + Iceberg) 解决”全量历史 + 跨引擎共享”,实时数仓 (ClickHouse) 解决”低延迟 + 高并发”。两个 hub 共存而不是替代:湖仓存”全部”,OLAP 物化”高频热查询的最近一段”。
- Airflow 和 Catalog 不是某一层的工具,而是横切:Airflow 调度所有计算任务,Catalog 给所有存储里的表登记元数据 — 它们的位置在图上特意从层带里挪出来。
下面按层逐个展开。
数据源 — 业务库 · 日志 · SaaS
这一层严格说不是”工具”,而是”数据从哪儿来”的事实清单。粗略分三类:
- 业务系统的关系库 — 订单 / 用户 / 库存 等,通常是 Postgres / MySQL / MongoDB / Oracle。特征:Schema 严格、单表行数从百万到亿,行级变更频繁。关键事实:这些库的真实 source-of-truth 是 WAL / binlog / oplog,而不是表本身;CDC 工具 都从这里读。
- 应用埋点与服务器日志 — 用户行为事件、APP / Web SDK 上报、后端 access log。特征:Schema 松散、字段繁多,append-only(几乎没有 update),单日体量 TB 级。
- 第三方 SaaS API — Salesforce(CRM)、Stripe(支付)、Google Ads(广告)、HubSpot(营销)等。特征:Schema 由对方决定,采集靠拉(API polling)或推(Webhook),频率从分钟到小时。
后面三层(Ingestion / Processing / Query)的选型,根本上由”你的数据源是哪一类、要求实时还是批”决定:CDC 路径走 Debezium → Kafka → Flink,埋点走 Kafka,SaaS 走 Airbyte / Fivetran。
数据集成 — Debezium · Kafka · Airbyte · Fivetran
数据集成层是 “把数据从源端搬到数据平台” 这一动作的工程化。关键的分裂在流式 vs 批量:数据库变更和事件流必须靠流式管道(Debezium → Kafka),SaaS 拉取适合做成定时批(Airbyte / Fivetran)。
Debezium · 数据库变更捕获 (CDC)
发展过程 — Debezium 由 Red Hat 主导,2016 年开源,捐给 CNCF Sandbox 项目。它的初衷是 “把数据库变更当作事件流”:不再 polling 整张表对比 diff,而是直接读 MySQL binlog / Postgres WAL / MongoDB oplog,把每一笔 INSERT / UPDATE / DELETE 实时转成 JSON 事件。早期 Debezium 紧绑 Kafka Connect 作为 runtime,2.0 版本(2022)推出 Debezium Server(独立 sink,可直接写 Pulsar / Kinesis / RabbitMQ)和 Debezium Engine(嵌入到任何 JVM 应用)。
核心设计 — 三层抽象:
- Connector — 每种数据库一个,负责读 WAL / binlog 并把变更格式化成统一的 Debezium 事件(
before/after/op(c/u/d) /ts_ms/source)。 - Runtime — Kafka Connect / Debezium Server / Debezium Engine,负责消费 Connector 输出并写到下游。
- Schema 注册与演化 — 通过 Confluent Schema Registry 或 Apicurio 维护 Avro / Protobuf schema,做 schema evolution。
CDC 的本质难点是 first-time snapshot + 后续 incremental 的无缝拼接。Debezium 用 “Watermark-based incremental snapshot” 解决:做 snapshot 的同时也吃 binlog,通过 watermark 标记 cut-off 点保证不漏不重。
用户情况 — LinkedIn(早期重要贡献者)、Convoy、WePay、京东、字节跳动等都在生产用 Debezium 跑 CDC 管道。国内常见组合是 Debezium + Kafka + Flink CDC(阿里贡献的 flink-cdc-connectors 项目本质上也是用 Debezium 的 Engine 库读 binlog)。是开源 CDC 事实标准,几乎没有有竞争力的开源替代(闭源端有 Fivetran HVR、Striim、Qlik Replicate)。
Demo 代码 — Debezium MySQL Connector 配置(Kafka Connect REST API 用 JSON 注册):
{
"name": "inventory-connector",
"config": {
"connector.class": "io.debezium.connector.mysql.MySqlConnector",
"database.hostname": "mysql-prod.internal",
"database.port": "3306",
"database.user": "debezium",
"database.password": "${SECRET:mysql_pwd}",
"database.server.id": "184054",
"topic.prefix": "inventory",
"database.include.list": "orders,inventory",
"table.include.list": "orders.line_items,inventory.products",
"schema.history.internal.kafka.bootstrap.servers": "kafka-1:9092",
"schema.history.internal.kafka.topic": "schema-changes.inventory",
"snapshot.mode": "initial"
}
}
注册之后,Kafka topic inventory.orders.line_items 里出现每行变更事件;消费者只要订阅这个 topic,就能拿到下游延迟 < 1 秒的同步流。
Kafka · 分布式提交日志
发展过程 — LinkedIn 在 2010 年内部启动 Kafka 项目(Jay Kreps、Neha Narkhede、Jun Rao),解决”用户活动事件 + 运维监控数据”两套系统重复造轮子的问题。2011 年开源,2012 年捐给 Apache,2014 年三位创始人离开 LinkedIn 成立 Confluent(商业化公司)。十几年里 Kafka 从单纯的消息队列演化成 “事件流平台”:
- 2015 — Kafka Connect(标准的连接器框架,Debezium 就是基于这个)
- 2016 — Kafka Streams(Java 客户端的流处理库,不需要外部集群)
- 2017 — KSQL(SQL on Kafka,后改名 ksqlDB)
- 2022 — KRaft(自管 metadata,逐步替代 ZooKeeper,生产可用)
- 2024 — Tiered Storage GA(冷数据下沉 S3,降低保留长尾日志的成本)
核心设计 — Kafka 的根基是把消息抽象成 “分区的有序追加日志”。
- Topic 切成多个 Partition,每个 Partition 在磁盘上就是一个顺序写文件;Consumer 用 offset 标记读到哪儿了。
- Broker 集群里每个 Partition 有 N 个副本,Leader 接读写、Followers 同步;ISR(In-Sync Replicas)机制保证 Leader 挂了立刻有副本接管。
- 关键 trade-off:顺序写磁盘 + 零拷贝 + page cache 让 Kafka 在普通硬件上单 Broker 就能跑到几十万 msg/s;但消费端必须自己处理 at-least-once 语义和 idempotent。
- KRaft 用 Raft 共识替代 ZooKeeper,把元数据也放进 Kafka 自身的日志里,部署形态从”两套集群”简化为”一套”。
用户情况 — Kafka 是事实标准的分布式数据总线。LinkedIn、Uber、Netflix、Airbnb、Twitter、阿里、字节、美团 都在用,LinkedIn 内部 Kafka 集群每天处理 7 万亿条消息。商业化层 Confluent(NASDAQ: CFLT,市值 $7B+)主要靠托管服务 Confluent Cloud 和 Kafka Streams / Connect / Schema Registry / ksqlDB 周边变现。竞品:
- Redpanda — C++ 重写,Kafka 协议兼容,主打更低延迟 / 没有 JVM / 没有 ZooKeeper
- Apache Pulsar — Yahoo! 开源,分离 broker / bookie,多租户特性更强
- AWS Kinesis / GCP Pub/Sub — 云厂商托管版,绑定生态但运维成本低
Demo 代码 — Java Producer + Consumer(Kafka 官方客户端,JVM 是其原生运行时):
import org.apache.kafka.clients.producer.*;
import org.apache.kafka.clients.consumer.*;
import org.apache.kafka.common.serialization.*;
import java.time.Duration;
import java.util.*;
Properties p = new Properties();
p.put("bootstrap.servers", "kafka-1:9092,kafka-2:9092");
p.put("key.serializer", StringSerializer.class.getName());
p.put("value.serializer", StringSerializer.class.getName());
try (var producer = new KafkaProducer<String, String>(p)) {
producer.send(new ProducerRecord<>("user.events", "u-42",
"{\"event\":\"login\",\"ts\":1715472000}"));
}
p.put("group.id", "analytics-pipeline");
p.put("auto.offset.reset", "earliest");
p.put("key.deserializer", StringDeserializer.class.getName());
p.put("value.deserializer", StringDeserializer.class.getName());
try (var consumer = new KafkaConsumer<String, String>(p)) {
consumer.subscribe(List.of("user.events"));
while (true) {
for (var r : consumer.poll(Duration.ofSeconds(1))) {
System.out.println(r.key() + " " + r.value());
}
}
}
Producer 按 key hash 写分区,Consumer 加入 group 自动分配分区做并行消费 — 这就是 Kafka “横向扩展” 在客户端看到的样子。
Airbyte · 开源 ELT 连接器
发展过程 — Airbyte 由前 LiveRamp 工程师 Michel Tricot 和 John Lafleur 于 2020 年创立。它瞄准的痛点是 “长尾 SaaS 数据源的连接器”:每家公司都要把 Stripe、Salesforce、Mixpanel、HubSpot、Intercom 等等的数据抽到自家数仓,但闭源 Fivetran 太贵、自研连接器又费力。Airbyte 主打 开源 + 社区贡献的连接器目录,目前已收录 600+ 个 Source / Destination connector。商业模式:Airbyte Open Source(MIT)+ Airbyte Cloud(SaaS,按行数计费)+ Airbyte Enterprise(自托管商业版)。2022 年 Series B 后估值 $1.5B。
核心设计 — Airbyte 把每个 connector 都打成 Docker 容器,通过 Airbyte Protocol(JSON over stdin/stdout)和调度器通信。这套设计让任何语言、任何依赖的 connector 都能接入。核心组件:
- Worker — 调度并运行 connector 容器
- Source / Destination Connector — 实际拉数据 / 写数据的容器,实现
spec/check/discover/read/write五个接口 - Connection — 把一个 Source 和一个 Destination 绑成一条同步任务,带 schedule、增量列、normalization 等配置
- CDK(Connector Development Kit)— Python / Low-code 模板,让贡献新 connector 的成本降到几百行 YAML
2023 年推出的 PyAirbyte 允许把 connector 当 Python 库直接调用,不需要起完整服务,在 notebook 场景很受欢迎。
用户情况 — 中型公司 + 数据团队是主力,Cargill、Calendly、Perplexity、Replicate 等都在用。是开源 ELT 工具事实标准。竞品:
- Meltano — GitLab 拆分独立运营,基于 Singer Tap 标准
- dlt(data load tool)— Python-native,主打”嵌入式 ELT”,受 dbt 启发
- Stitch — Talend 收购,SaaS-only,Singer 协议作者
- Hevo Data — 印度团队,商业 SaaS
Demo 代码 — Airbyte 的 manifest.yaml(低代码 connector,声明式拉一个 REST API):
version: 0.50.0
type: DeclarativeSource
streams:
- name: customers
primary_key: ["id"]
retriever:
record_selector:
extractor:
field_path: ["data"]
requester:
type: HttpRequester
url_base: "https://api.example.com/v1"
path: "/customers"
http_method: "GET"
authenticator:
type: BearerAuthenticator
api_token: "{{ config['api_key'] }}"
paginator:
type: DefaultPaginator
page_token_option:
type: RequestOption
field_name: "cursor"
inject_into: "request_parameter"
这套 YAML 就是一个完整的 Airbyte Source connector,不用写一行 Python。
Fivetran · 闭源托管 ELT
发展过程 — Fivetran 由 George Fraser 和 Taylor Brown 2012 年在 YC W13 创立,比 Airbyte 早八年。主打 “零维护的 SaaS 同步” — 客户连授权、不用部署、不用维护 connector,完全 SaaS 化。这套定位在云数仓兴起(Snowflake、BigQuery、Redshift)的 2017-2020 年成为标配 ELT,2021 年 Series D 估值 $5.6B,后来跟 HVR 合并补足了 CDC 能力。商业模式纯按 MAR(月活跃行数) 计费,定价是数据栈里最贵的层之一 — 这也催生了 Airbyte 这种开源替代。
核心设计 — Fivetran 用统一的”Schema-on-write”模型:每个 connector 把源端 schema 自动复制到目标数仓,新增列 / 新增表自动同步。CDC 用 binlog,SaaS 用 API。所有 connector 闭源、Fivetran 自己维护质量与升级。这一点和 Airbyte 形成清晰对照:Fivetran 卖的是”省心”,Airbyte 卖的是”可控 + 便宜”。
用户情况 — Notion、Square、DocuSign、Autodesk 等大量上市公司用 Fivetran。配合 Snowflake / BigQuery / dbt 形成 “现代数据栈” 三件套(EL → Fivetran;T → dbt;Storage → Snowflake)。
Demo 代码 — Terraform 配置 Fivetran connector(实际上 Fivetran 自己是 UI/API 驱动,但用 Terraform 管理是社区主流做法):
resource "fivetran_connector" "stripe_to_snowflake" {
group_id = fivetran_group.prod.id
service = "stripe"
sync_frequency = 60 # minutes
destination_schema {
name = "stripe_raw"
}
config {
secret_key = var.stripe_secret_key
}
}
resource "fivetran_connector_schedule" "stripe_schedule" {
connector_id = fivetran_connector.stripe_to_snowflake.id
schedule_type = "auto"
paused = false
}
写完 terraform apply,几分钟后 Snowflake 里就出现 stripe_raw.charges / stripe_raw.customers 等几十张表,完全镜像 Stripe API 的对象模型。
计算处理 — Spark · Flink · dbt
数据进了平台之后,要做清洗、聚合、关联、特征工程,这就是计算层的工作。三大主流引擎按”处理范式”划界:Spark 重型批 + 通用计算,Flink 流原生 + 有状态计算,dbt SQL 模板 + 数仓内变换。
Apache Spark · 分布式批处理与 ML
发展过程 — Spark 起于 UC Berkeley AMPLab(2009),Matei Zaharia 博士论文项目,2010 年开源,2014 年捐给 Apache 成为顶级项目。当时正值 Hadoop MapReduce 笨重且慢的痛点期,Spark 提出 RDD(Resilient Distributed Dataset) 抽象 + 内存计算,把 MapReduce 一轮 IO 写盘的开销省掉,典型 ETL 任务跑得快 10-100 倍。后续演化:
- 2014 — Spark SQL + DataFrame API(SQL 优化器 Catalyst)
- 2016 — Structured Streaming(微批流处理)
- 2018 — Spark 2.4 推出 Spark on K8s
- 2020 — Spark 3.0 + Adaptive Query Execution(AQE)
- 2023 — Spark Connect(C/S 架构,客户端瘦身)
- 2024 — Photon(Databricks 商业版的 C++ 向量化执行引擎)+ Spark 4.0
Matei 创立的 Databricks(2013)成为 Spark 商业母舰,2024 年估值 $62B,IPO 倒计时。云上 Spark = Databricks,本地 Spark 也大量被 EMR / Dataproc 托管。
核心设计 — Spark 的核心是 “分阶段的有向无环图执行”:
- DataFrame / Dataset API → Catalyst 优化器(基于规则 + 基于代价)→ 物理计划 → DAG of Stages → Tasks
- Stage 之间 用 shuffle 切分(类似 MapReduce 但在内存里 spill)
- AQE 在 runtime 根据真实数据分布调整 join 策略 / shuffle 分区数 — 是 Spark 3+ 性能大跃进的关键
- 数据可以来自 HDFS / S3 / JDBC / Iceberg / Delta / Kafka,统一抽象成 DataFrame
- ML(MLlib)和 GraphX 是同一引擎的子模块,使 Spark 也是大规模特征工程的常用工具
用户情况 — 几乎所有大型数据团队都在用。Apple、Uber、Netflix、LinkedIn、字节、阿里、腾讯 都有 PB 级 Spark workload。Spark 的优势在 批处理的全面性 + ML 集成,劣势在流处理(微批的延迟比不过 Flink)。常见组合:Iceberg + Spark + Airflow 跑日级 / 小时级 ETL。
Demo 代码 — Scala 一段聚合作业(读 Iceberg,写回 Iceberg)。Spark 本体用 Scala 写,Scala API 是最贴近引擎的写法:
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions._
val spark = SparkSession.builder
.appName("daily_orders_summary")
.config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions")
.config("spark.sql.catalog.iceberg", "org.apache.iceberg.spark.SparkCatalog")
.config("spark.sql.catalog.iceberg.type", "glue")
.getOrCreate()
import spark.implicits._
val orders = spark.read.table("iceberg.raw.orders").where($"status" === "paid")
val daily = orders
.groupBy(to_date($"created_at").as("day"), $"country")
.agg(count("*").as("order_count"),
sum($"total_cents").as("gmv_cents"))
.orderBy("day", "country")
daily.writeTo("iceberg.marts.daily_orders").overwritePartitions()
跑这段作业,Spark 自动把 Iceberg 表的 partition pruning、predicate pushdown、shuffle 调优全部接管。
Apache Flink · 流原生有状态计算
发展过程 — Flink 起于柏林工业大学的 Stratosphere 研究项目(2010),核心团队 Stephan Ewen、Kostas Tzoumas 等 2014 年成立 Data Artisans 公司并把 Stratosphere 重命名为 Flink 捐给 Apache,同年成为顶级项目。Flink 的杀手锏是 真流式 + 事件时间(event time) + 精确一次(exactly-once) 语义,这三件事在 Spark Streaming 时代是 trade-off,Flink 给出了一体化方案。
2019 年阿里巴巴 €90M 收购 Data Artisans,改名 Ververica,Flink 在阿里巴巴大规模落地双十一实时大屏 / 实时风控 / 实时推荐。2023 年 Confluent 收购 Immerok(原 Data Artisans 创始团队后续创业项目),押注 “Kafka + Flink” 一体的事实标准。
核心设计 — Flink 的核心抽象是 DataStream(无界流)和 State(算子持有的本地状态)。
- 事件时间 + Watermark — 数据带时间戳,Watermark 告诉系统”我可以认为 t 之前的事件都到了”,从而做正确的窗口聚合
- Checkpoint / Savepoint — 用 Chandy-Lamport 算法定期对所有算子的状态做分布式快照,失败时回滚到最近的 checkpoint,实现 exactly-once
- State Backend — 状态可放堆内、堆外、RocksDB(默认大状态场景);RocksDB 状态可以挂 S3 做增量 checkpoint
- Flink SQL / Table API — 上层 SQL 接口,跟 Kafka / Iceberg / JDBC 接得很顺,降低使用门槛
用户情况 — 阿里巴巴(全集团)、Uber(实时定价)、Netflix(实时推荐特征)、LinkedIn(实时数据流)、字节跳动(实时数仓)、滴滴(实时风控)等。国内大厂的实时数仓默认引擎。竞品:
- Spark Structured Streaming — 微批,延迟秒级以上,但 Spark 生态一体化
- Kafka Streams — Java 客户端库,轻量但只能在 JVM 内、强绑 Kafka
- Materialize — 基于 Differential Dataflow,SQL-first,增量物化视图
- RisingWave — 中国团队开源,定位类似 Materialize
Demo 代码 — Flink SQL 实时聚合 Kafka 流写入 Iceberg:
-- Source: Kafka topic
CREATE TABLE orders_stream (
order_id BIGINT,
user_id BIGINT,
amount_cents BIGINT,
ts TIMESTAMP_LTZ(3),
WATERMARK FOR ts AS ts - INTERVAL '5' SECOND
) WITH (
'connector' = 'kafka',
'topic' = 'orders.v1',
'properties.bootstrap.servers' = 'kafka:9092',
'format' = 'json',
'scan.startup.mode'= 'latest-offset'
);
-- Sink: Iceberg table
CREATE TABLE orders_5m_agg WITH (
'connector' = 'iceberg',
'catalog-name' = 'glue',
'database-name' = 'marts'
) AS
SELECT
TUMBLE_START(ts, INTERVAL '5' MINUTE) AS window_start,
COUNT(*) AS orders,
SUM(amount_cents) AS gmv_cents
FROM orders_stream
GROUP BY TUMBLE(ts, INTERVAL '5' MINUTE);
提交后 Flink 持续消费 Kafka,按 5 分钟事件时间窗口聚合,exactly-once 写到 Iceberg,延迟在秒级。
dbt · 数仓内 SQL 建模
发展过程 — dbt(data build tool)由 Tristan Handy 在 2016 年于咨询公司 Fishtown Analytics(后改名 dbt Labs)创立,核心团队 Drew Banin、Connor McArthur、Jason Ganz。dbt 没有发明新的计算引擎,它就是一个 SQL 模板编译器 + 执行框架 — 把 models/orders.sql 编译成 CREATE TABLE ... 推到 Snowflake / BigQuery / Redshift / Databricks / Postgres / Trino / DuckDB 执行。
它的爆发逻辑是:云数仓时代,计算交给 Snowflake,数据团队真正需要的是 “工程化的 SQL 工作流” — 版本控制、依赖管理、测试、文档、CI/CD。dbt 完美填补这个空缺,并催生了 “Analytics Engineer” 这个新职位类型。2022 年 Series D 估值 $4.2B。商业层 dbt Cloud(托管 IDE + 调度 + 文档)是主要收入。2024 年发布 dbt Fusion(基于 SDF 收购的 Rust 引擎,把 SQL 解析 / 模型解析的性能提升 30 倍)。
核心设计 — 围绕几个关键概念:
- Model — 一个
.sql文件,内容是一个 SELECT,dbt 编译成CREATE TABLE / VIEW AS {{ ref('upstream_model') }}— 模型间引用,dbt 自动构建 DAG 决定执行顺序{{ source('raw', 'orders') }}— 引用原始表,与下游模型解耦- Test — 内置
unique/not_null/accepted_values/relationships,加自定义 SQL 测试 - Macro — Jinja 模板,复用 SQL 片段
- Snapshot — SCD Type 2 历史维表
- Materialization —
view/table/incremental/ephemeral,改一个配置就能从全量改增量 - Package — 像 npm 一样从 dbt Hub 装别人写的 model / macro 集合
dbt 的强势在于 把分析工作流强制规约成”软件工程”:每个 model 都有 owner、有测试、有文档,通过 git 提交、走 CI、Pull Request review,与十年前”在 BI 里写一段 ad-hoc SQL”的混乱形成鲜明对比。
用户情况 — 几乎所有 modern data stack 团队的标配,JetBlue、Casper、HubSpot、GitLab、Notion、Vercel 等公司都在用。事实标准。开源生态 dbt-utils / dbt-expectations / elementary / re_data 极活跃。竞品:
- SQLMesh — Toby Mao(Airbnb)等开源,主打”自动 schema migration + 真正的 column-level lineage”
- Dataform — Google 收购,集成在 BigQuery 里
- Lea — 简化版 SQL build tool,Python 一体化
Demo 代码 — 一个 incremental 模型 + 测试:
-- models/marts/fct_orders.sql
{{ config(
materialized='incremental',
unique_key='order_id',
on_schema_change='append_new_columns'
) }}
select
o.order_id,
o.user_id,
o.created_at,
o.total_cents,
u.country
from {{ source('raw', 'orders') }} o
left join {{ ref('dim_users') }} u using (user_id)
{% if is_incremental() %}
where o.updated_at >= (select coalesce(max(updated_at), '1970-01-01') from {{ this }})
{% endif %}
# models/marts/_schema.yml
version: 2
models:
- name: fct_orders
columns:
- name: order_id
tests: [unique, not_null]
- name: user_id
tests:
- relationships:
to: ref('dim_users')
field: user_id
dbt run --select fct_orders 之后,dbt 编译成 MERGE INTO / INSERT INTO 推到目标数仓,再跑 dbt test 验证。
存储 — 湖仓 (S3 + Iceberg) · 实时 OLAP (ClickHouse)
存储层这几年最大的变化是 “湖仓一体”(Lakehouse)取代了”数据湖 vs 数据仓库”的二元对立。底层是 S3 / R2 这种廉价对象存储,上面盖一层 开放表格式(Iceberg / Delta / Hudi)提供 ACID + schema evolution,任何计算引擎都能读写。实时 OLAP 是另一个并存的形态:数据物化在 ClickHouse / Doris / StarRocks 这种存算一体引擎里,牺牲多引擎共享换取毫秒级响应。
S3 / R2 · 对象存储底座
发展过程 — Amazon S3 于 2006 年发布,是云计算的第一个对象存储,也是最古老的 AWS 服务之一。它的 11 个 9(99.999999999%)的 durability、99.99% 的可用性、单桶无限对象数,直接把 “如何安全保存 PB 级数据” 这个问题杀死。Cloudflare R2(2022 年 GA)的差异点在 “零 egress” — S3 的出网流量贵到能让”我把数据从 AWS 拉出去用”几乎不可行,R2 把这个壁垒拆掉,迫使 AWS 在 2024 年也宣布免费 egress(有条件)。另外两个常被列名的:Google Cloud Storage(GCS)、Backblaze B2。
核心设计 — S3 是 HTTP REST + 强一致性 + 对象不可变 的存储模型:
- 单对象上传一次后不能改(覆盖即新版本),适合 append-only 数据
- 用 prefix(伪目录) 组织,但不是真正的目录树 — 列出某 prefix 下的 keys 是 O(n) 扫描
- 提供分级存储:Standard / Infrequent / Glacier(冷存),按存储 + 请求 + 出网三维度计费
- 同区域内带宽几乎免费,跨区域 / 出网到互联网才贵
S3 的一个关键约束:LIST 操作慢(默认 1000 key/页,大目录扫几分钟),所以湖仓表格式(Iceberg / Delta)都必须维护自己的 manifest 文件来避免 LIST。
用户情况 — 几乎所有现代云原生数据平台的底层。S3 上有大约百亿亿 GB 数据(2023 公开数据)。R2 增长迅速,Cloudflare 2024 报告 R2 已存储数十亿亿对象。
Demo 代码 — AWS CLI(对象存储日常 ops 的最常用入口):
# 写入(单文件加 SSE 加密)
aws s3 cp part-00.parquet \
s3://my-lakehouse/raw/orders/dt=2026-05-11/part-00.parquet \
--sse AES256
# 同步整个目录(增量,只传变化文件)
aws s3 sync ./local-dir/ s3://my-lakehouse/raw/orders/dt=2026-05-11/
# Cloudflare R2 兼容 S3 API,只需切 endpoint
aws s3 cp file.parquet s3://my-r2-bucket/path/ \
--endpoint-url https://<account>.r2.cloudflarestorage.com
实际生产里数据写入很少这样裸操作,基本都通过 Iceberg / Spark / Trino 间接读写;CLI 留给运维侧:bucket policy、生命周期规则、巡检。
Apache Iceberg · 开放表格式
发展过程 — Iceberg 2017 年由 Ryan Blue 和 Daniel Weeks 在 Netflix 启动,2018 开源,2020 进 Apache 顶级项目。它要解决的核心痛点是 Hive table format 在大数据湖场景下的几个致命缺陷:
- LIST 整个 partition 找文件慢
- 没有 ACID,并发写常踩坏
- 没有 schema evolution(只能加列、不能改类型 / rename)
- 没有时间旅行 / rollback
Iceberg 的解法是 “在文件层之上盖一层独立的 metadata 层”:每张表有 metadata.json 指向 manifest list,manifest list 指向 manifest files,manifest 才指向数据文件 — 形成三层指针。每次写都生成新一份 metadata.json,通过原子重命名实现 ACID。
2024 年 Snowflake 以 $1B+ 收购 Tabular(Ryan Blue 与 Daniel Weeks 创办、Iceberg 主要商业实体),与 Databricks 收购 Tabular 失利后转去收购 Delta Lake 的运营公司形成对照。Iceberg 已成事实标准:AWS Glue、Athena、Snowflake、BigQuery、Databricks(自 2024 起也原生支持)、Cloudflare R2 SQL、ClickHouse、Trino、Flink、Spark 全部能读 Iceberg。
核心设计 — 三层 metadata:
- Metadata file(JSON)— 表 schema、partition spec、snapshots 列表、当前快照指针
- Manifest list(Avro)— 一次写入产生一个,列出本次写入涉及的所有 manifest 文件
- Manifest file(Avro)— 列出具体数据文件(Parquet / ORC / Avro)的路径、统计、partition value
读取路径:用 manifest 的 column statistics(min/max)做 partition + file pruning,避免扫无关数据。 写路径:每次 commit 原子替换 metadata file 指针,做 MVCC。
trade-off:Iceberg 不绑特定计算引擎(对比 Delta Lake 早期紧绑 Spark),但 commit 冲突时要重试。
用户情况 — Netflix、Apple、AirBnB、Adobe、字节、Stripe 等大型数据湖的主流选择。竞品:
- Delta Lake — Databricks 主导,2019 部分开源、2022 全开源(Delta Lake 3.0 UniForm 支持 Iceberg metadata 双写)。生态在 Databricks 平台最完整
- Apache Hudi — Uber 2017 开源,主打 upsert + incremental query,在 CDC / 高 upsert 场景仍有优势,但社区动能弱于 Iceberg
Demo 代码 — Spark SQL 创建 + 维护 Iceberg 表:
-- 创建表
CREATE TABLE iceberg.marts.fct_orders (
order_id BIGINT,
user_id BIGINT,
amount_cents BIGINT,
country STRING,
created_at TIMESTAMP
)
USING iceberg
PARTITIONED BY (days(created_at), country)
TBLPROPERTIES (
'write.format.default' = 'parquet',
'write.target-file-size-bytes' = '134217728'
);
-- Upsert
MERGE INTO iceberg.marts.fct_orders t
USING staging.orders_delta s
ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;
-- 时间旅行
SELECT * FROM iceberg.marts.fct_orders
FOR TIMESTAMP AS OF '2026-05-10 00:00:00';
-- 删除旧 snapshot (compaction + GC)
CALL iceberg.system.expire_snapshots('marts.fct_orders', TIMESTAMP '2026-05-01');
ClickHouse · 实时 OLAP
发展过程 — ClickHouse 起源于 Yandex 在 2009 年的内部项目,用来支撑 Yandex.Metrica(俄罗斯版 Google Analytics)的报表查询 — 当时每天处理数百亿事件,要在 sub-second 出聚合结果。2016 年开源,迅速成为开源 OLAP 引擎事实标杆。2021 年原核心团队成立 ClickHouse Inc.(美国),从 Yandex 独立出来,2024 年估值 $6B。商业化主推 ClickHouse Cloud(托管)。
核心设计 — ClickHouse 的所有性能优势都来自 列存 + MergeTree + 向量化执行 三个根基:
- MergeTree 引擎是默认的表引擎家族(含 ReplacingMergeTree / SummingMergeTree / AggregatingMergeTree 等变体),按 ORDER BY 排序写入,后台合并小文件成大文件 — 类似 LSM-tree 思想
- 数据按列存储,只读到查询用到的列,IO 跟列数线性相关而不是行数
- 向量化执行 — 每次处理一批(1024 行)而不是一行,用 SIMD 极致优化
- 稀疏索引 — 每 N 行一个索引点,通过 ORDER BY 的前缀字段做 range scan
- Distributed table + 分片 + 副本做横向扩展
- 物化视图 — 写入时实时聚合(本质是在写路径上挂个 trigger,SummingMergeTree 类引擎自动做增量)
trade-off:写入快 / 查询快 / 但 UPDATE / DELETE 弱(异步、效率低,只能批量)。这意味着 ClickHouse 是典型的”append-mostly”工具,做实时数仓和 OLAP 完美,做事务库不行。
用户情况 — Cloudflare(原始日志分析,日均上百亿事件)、Uber(实时风控)、字节跳动(用户行为分析,Cnch 是字节自研的 ClickHouse 改造版)、Spotify、eBay、Disney、滴滴、阿里(Hologres 团队曾是 ClickHouse 重要贡献者)等。 竞品:
- Apache Doris(原 PaloDB,百度,2017 开源,2022 进 Apache)— 国内大量金融 / 政企案例
- StarRocks(Doris fork,2020 开源,Mirror 创立公司商业化)— 国内字节 / 腾讯 / 美团等
- Druid(Imply 商业化,Metamarkets 出身)— 老牌实时 OLAP
- Pinot(LinkedIn 开源,2018 进 Apache)— LinkedIn / Uber 在用
Demo 代码 — 建表 + 物化视图:
-- 明细表
CREATE TABLE events (
event_date Date,
event_time DateTime,
user_id UInt64,
event_type LowCardinality(String),
country LowCardinality(String),
revenue_cents UInt64
)
ENGINE = MergeTree
PARTITION BY event_date
ORDER BY (event_date, event_type, user_id)
TTL event_date + INTERVAL 90 DAY;
-- 物化视图:每小时聚合
CREATE MATERIALIZED VIEW events_hourly_mv
ENGINE = SummingMergeTree
PARTITION BY event_date
ORDER BY (event_date, event_hour, country, event_type)
AS SELECT
event_date,
toStartOfHour(event_time) AS event_hour,
country,
event_type,
count() AS events,
sum(revenue_cents) AS revenue_cents
FROM events
GROUP BY event_date, event_hour, country, event_type;
-- 查询(命中物化视图,毫秒级响应)
SELECT country, sum(revenue_cents) / 100 AS revenue_usd
FROM events_hourly_mv
WHERE event_date = today() AND event_type = 'purchase'
GROUP BY country ORDER BY revenue_usd DESC LIMIT 10;
查询服务 — Trino · Spark SQL · Redis
存储层有数据之后,需要一个”查询入口”把 SQL / KV 请求接住。Trino 负责跨源联邦的交互式 SQL,Spark SQL 负责重的分析 / 特征工程(就是 §04 里的 Spark,以 SQL 形态对外),Redis 负责 KV / 缓存 / 在线指标。
Trino · 联邦 SQL 引擎
发展过程 — Trino 的前身是 Presto,由 Facebook 在 2012 年开发(Martin Traverso、David Phillips、Eric Hwang、Dain Sundstrom),用于把 Hadoop 上的交互式 SQL 跑到秒级响应。2013 年开源,迅速成为业界 MPP SQL 引擎代表。2018 年原核心团队因与 Facebook 的治理矛盾出走,fork 出 PrestoSQL(后来 2020 年改名 Trino,因 Facebook 把 Presto 商标捐给了 Linux Foundation 但保留了治理),并成立 Starburst 公司做商业化。今天市场说的 Presto 一般都指 Trino,原 PrestoDB 由 Linux Foundation 维护但活跃度低。
Trino 的核心定位是 “用一套 SQL 引擎查所有数据源”:不复制数据、不要求统一格式,通过 connector 直接联邦查询 Hive / Iceberg / Delta / MySQL / Postgres / Kafka / Elasticsearch / Cassandra / MongoDB … 50+ 种数据源。
核心设计 — Trino 是 shared-nothing MPP:
- 一个 Coordinator(SQL parse + plan + schedule)
- N 个 Worker(执行物理算子)
- Connector 抽象 — 每种数据源实现
ConnectorMetadata/ConnectorSplitManager/ConnectorPageSource,数据以 page(列批)形式在 worker 间流动 - 完全内存 + 流水线执行,中间结果不落盘(这也是 Trino 不适合超大 batch 的原因 — OOM 风险)
- 支持 dynamic filtering(运行时把 build side 的 join key 推到 probe side 做下推)
trade-off:Trino 强在 交互式查询(秒级响应)+ 跨源 join,弱在长跑的容错(失败重跑代价大,3.x 引入 fault-tolerant execution 部分缓解)。
用户情况 — Netflix(主要交互查询入口)、LinkedIn、Lyft、Pinterest、Stripe、字节 等。Starburst Galaxy(托管 Trino)是商业主力。竞品:
- Apache Spark SQL — 偏批,生态更广
- Apache Doris / StarRocks / ClickHouse — OLAP 数据库,要求数据先入库
- DuckDB — 单机分析,在 < 100GB 场景常常更快
- AWS Athena — Trino 的 AWS 托管商业版本,主要查 S3 + Iceberg
Demo 代码 — Trino 跨 Iceberg + MySQL 联表(经典场景:把 OLTP 的维度表和 lakehouse 的事实表 join):
SELECT
o.country,
p.product_name,
SUM(o.amount_cents) / 100 AS revenue_usd
FROM iceberg.marts.fct_orders o
JOIN mysql.production.products p
ON o.product_id = p.id
WHERE o.created_at >= DATE '2026-05-01'
AND o.country IN ('US', 'JP', 'CN')
GROUP BY 1, 2
ORDER BY revenue_usd DESC
LIMIT 50;
Trino 在执行时:Iceberg connector 读 S3,MySQL connector 读 prod DB,join 在 worker 内存里做。整张表只在查询时联起来,无需事先 ETL。
Spark SQL · 指向 §04 计算
Spark SQL 已在 §04 计算处理 里展开,这里只点出”查询身份”的视角差异:
- 同一个 Spark cluster,既能跑离线 ETL(
spark-submit提交作业),也能挂个 Thrift Server(JDBC / ODBC 端口)接 SQL 客户端 — 这时它就是个”准实时 SQL 引擎” - 对比 Trino:Spark SQL 适合重型分析(分钟级 OK 但容错强),Trino 适合交互式查询(秒级要快但容错弱)
- ML 特征工程默认选 Spark SQL(因为下游就是 PySpark MLlib / Pandas API),BI dashboard 默认选 Trino
Redis · 缓存与 KV
发展过程 — Redis 由 Salvatore Sanfilippo 2009 年用 C 写出(意大利程序员,业余项目),解决他的实时统计网站性能问题。2010 年项目被 VMware 雇佣继续开发,2015 年 Redis Labs(后改名 Redis Inc.)接手主导。十几年里 Redis 从 “in-memory KV” 演化成 “in-memory data structure server”:string / hash / list / set / sorted-set / bitmap / hyperloglog / stream / geo / json(模块)/ vector(模块)— 几乎任何业务场景都能映射到一种 Redis 结构。
2024 年 3 月,Redis 把 license 从 BSD 改为 RSALv2 + SSPL(双 license,限制云厂商商用),社区当即在 Linux Foundation 下 fork 出 Valkey,AWS / Google / Oracle / Snowflake 都投入工程力量;同期 Redict、Garnet(微软,C# 写,主打更高吞吐)等竞品涌现。今天讨论”Redis 替代品”已成数据栈的真问题。
核心设计 — Redis 是典型的 “单线程事件循环 + in-memory 数据结构”:
- 所有命令在一个主线程串行执行(IO 多路复用模式),所以无需锁
- 持久化:RDB(快照)+ AOF(append-only log)双重保险
- 高可用:Sentinel(主从切换)或 Cluster(分片)
- Redis Modules(7.0 之后)允许第三方扩展数据类型:RedisJSON、RedisSearch、RedisGraph、RedisAI、RediSearch + Vector 都在生产中
- 6.0 引入多线程 IO(单线程命令处理保留,但 IO 多线程),吞吐再上一个台阶
用户情况 — 几乎所有互联网公司都跑着 Redis:Twitter、GitHub、Stack Overflow、Snapchat、Pinterest 等。数据栈里的典型用法:
- 把 ClickHouse / Trino 的查询结果按 key 缓存到 Redis(避免重复查询)
- 作为实时指标的 hot store(把 Flink 实时 sink 进 Redis)
- 作为 ML 特征 store 的 online 部分(Feast 等 feature store 默认配 Redis)
Demo 代码 — Go 缓存 + sorted-set 实时排行榜(Redis 最典型的消费者是 Go / Java 写的后端服务):
package main
import (
"context"
"encoding/json"
"time"
"github.com/redis/go-redis/v9"
)
func main() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{Addr: "redis.internal:6379"})
// 1. 缓存查询结果(5 分钟 TTL)
cacheKey := "top_countries:2026-05-11"
if v, err := rdb.Get(ctx, cacheKey).Result(); err == nil {
var cached []Row
json.Unmarshal([]byte(v), &cached)
} else {
rows := expensiveClickHouseQuery()
b, _ := json.Marshal(rows)
rdb.Set(ctx, cacheKey, b, 5*time.Minute)
}
// 2. Sorted set 实时排行榜
for _, u := range updates {
rdb.ZIncrBy(ctx, "leaderboard:2026-w19", u.Score, u.UserID)
}
// 3. 拿 Top 10
top10, _ := rdb.ZRevRangeWithScores(ctx, "leaderboard:2026-w19", 0, 9).Result()
_ = top10
}
应用层 — BI · 后端 API · ML 应用
应用层是数据最终被”用掉”的地方。这一层的工具不像底层那样”互斥”,而是 按用户角色分流:数据分析师用 BI 看板,业务系统用后端 API,算法 / ML 团队用模型推理。
Apache Superset · 数据分析平台
发展过程 — Superset 由 Maxime Beauchemin 在 Airbnb 2015 年内部开发(Airflow 的同一个作者!),2016 开源,2017 进 Apache 孵化器,2021 成为顶级项目。Maxime 离开 Airbnb 后创立 Preset(2019),做 Superset 的 SaaS 托管。Superset 的设计哲学是 “探索导向 + 工程师友好”:写 SQL 探索 → 保存为 dataset → 加图表 → 拼 dashboard,整个链路在网页里走完。
核心设计 — 三个核心抽象:
- Database connection — 通过 SQLAlchemy / DB API 连一切支持 SQL 的源(Trino / Iceberg via Trino / ClickHouse / Postgres / Snowflake / BigQuery …)
- Dataset — 一个 SQL query 或表,作为后续图表的数据来源
- Chart / Dashboard — 80+ 种可视化(基于 ECharts / Plotly)
特色:SQL Lab(浏览器内 SQL 编辑器,带语法高亮 + 自动补全 + 历史);Jinja templating(SQL 里能写 {{ filter_values('country') }} 动态拼);Row-level security(按用户给行加 WHERE 子句);Embedded analytics(SDK 嵌进自家产品)。
用户情况 — Airbnb、Lyft、Twitter、AT&T、Bloomberg、字节、京东、滴滴 等。开源 BI 第一梯队。Preset Cloud 是托管版商业化。
Demo 代码 — Superset 的 dataset YAML(用 superset import-datasources 批量管理):
database_name: trino-lakehouse
sqlalchemy_uri: trino://datateam@trino-prod.internal:8443/iceberg
tables:
- table_name: fct_orders_daily
schema: marts
columns:
- column_name: day
type: DATE
is_dttm: true
- column_name: country
type: VARCHAR
- column_name: gmv_cents
type: BIGINT
metrics:
- metric_name: gmv_usd
expression: "SUM(gmv_cents) / 100.0"
- metric_name: orders
expression: "SUM(order_count)"
Metabase · 自服务 BI
发展过程 — Metabase 由 Sameer Al-Sakran 2015 年开源,Metabase Inc. 是同期成立的商业母舰。它的定位和 Superset 错开:“非技术用户也能用” — 通过 UI 选维度 / 度量 / 过滤生成查询,而不需要写 SQL。Metabase 2024 年 Series D 估值 $1.6B。商业模式:开源(AGPL)+ Pro / Enterprise(闭源增值)+ Cloud。
核心设计 — 围绕 “Question” 这个抽象:每个图表是一个 question,question 可以通过 Notebook(UI 拖拽)或 SQL 编辑器构造。
- X-ray — 自动对一张表 / 一段 segment 做自动探索,弹出常见问题与图表(适合不知道从哪儿下手的用户)
- Dashboard + Subscription — 仪表盘定时邮件推送(管理层最常用)
- Models(其实是 view + metadata)— 类似 dbt model,在 BI 层定义 “干净的表”
- Embedding — 把 dashboard 嵌入自家产品(JWT 签名 + Iframe)
用户情况 — 中小公司主流,GitHub 上 39k+ star。和 Superset 比:Metabase 更轻量 / 易上手,但定制 / 可视化丰富度不如 Superset。中型公司常常两个都装:Metabase 给业务 PM 用,Superset 给数据分析师用。
Demo 代码 — Metabase 是个纯 HTTP API,curl 是最直接的演示:
# 登录拿 session token
TOKEN=$(curl -s https://metabase.internal/api/session \
-H "Content-Type: application/json" \
-d '{"username":"bot","password":"secret"}' | jq -r .id)
# 跑一个 saved question(id=42)拿 JSON 结果
curl -s -X POST https://metabase.internal/api/card/42/query/json \
-H "X-Metabase-Session: $TOKEN" | jq '.[0:3]'
实际生产用 Metabase 的脚本场景很少,绝大多数交互都通过 Web UI。
后端 API / ML 应用 · 不是单一工具
后端 API 这一格不是某个具体项目,而是把数据平台的查询能力暴露给业务系统的 应用代码:
- 一个 FastAPI / Spring Boot / Go 服务,内部把请求翻译成 Trino / ClickHouse 查询 + Redis 缓存
- 或者前端通过 GraphQL gateway(Hasura、PostGraphile)直接拉数仓表
- 或者数据反向同步回 OLTP 库(reverse ETL,Hightouch / Census 这类工具)
ML 应用同理,典型链路:
- 特征工程 → Spark + Iceberg / Flink + Redis(Feast 这类 feature store 把 offline / online 两端管起来)
- 训练 → Spark MLlib / PyTorch on Ray / sklearn / xgboost / lightgbm
- 推理 → 推理服务(Triton、TorchServe、KServe)+ Redis vector / Qdrant / Pinecone 做向量检索
- RAG / LLM → 在数据栈上叠一层 vector DB,与传统 OLAP 并行存在
这一层 没有”主流单一工具”,而是几十种轻量服务的拼装。是数据团队和业务工程团队的接口。
编排与治理 — Airflow · Glue Catalog · DataHub
调度和治理是横切关注。Airflow 决定”什么任务什么时候跑、什么依赖什么”,Glue Catalog 决定”我这张表的 schema 是什么”,DataHub 决定”这张表的血缘是怎么来的、谁拥有它、质量如何”。
Apache Airflow · 工作流编排
发展过程 — Airflow 由 Maxime Beauchemin 在 Airbnb 2014 年开发(同 Superset 同一个作者),2015 开源,2016 进 Apache 孵化,2019 成为顶级项目。它的核心创新是 “workflow as Python code” — DAG 不写 YAML 不写 XML 而是写 Python,任务依赖通过 Python 函数调用顺序声明。这个理念在 2015 年还不主流(当时 Oozie / Azkaban 是 XML / YAML 派),但很快成为标准。Astronomer 是商业母舰,2022 估值 $1.7B,2024 收购 Datakin(OpenLineage)。
核心设计 — 主要概念:
- DAG — 一个 Python 文件 = 一个 DAG,通过
@dag/@task装饰器或 Operator 实例描述 - Operator — 一个 task 类型(BashOperator / PythonOperator / SparkSubmitOperator / KubernetesPodOperator …)
- Sensor — 等待某条件成立(文件出现 / 时间到 / 上游任务完成)
- Scheduler / Worker / Webserver — 三大组件,可分布式部署
- XCom — task 之间传递小值(< 几 KB)
- TaskFlow API(2.0+)— 用纯 Python 装饰器声明依赖,DAG 写起来像普通代码
- Provider package — 接 Snowflake / dbt / Databricks / GCP / AWS / Slack 等几百种系统的官方插件
用户情况 — 几乎所有数据团队都在跑 Airflow。Airbnb、Lyft、Square、Robinhood、Tesla、Google(Cloud Composer 就是托管 Airflow)、AWS(MWAA)、字节、滴滴等。竞品的差异化:
- Dagster — Elementl 公司开源,主打 asset-centric(以”数据资产”为一等公民,不是 task)
- Prefect — Python-first,主打”代码即调度,基本不需要新的 DSL”,简洁
- Argo Workflows — 完全 K8s 原生,YAML DAG,运维偏 SRE
- Mage / Kestra / Temporal — 各自有差异点(UI 友好 / YAML / 长时间运行的 stateful workflow)
Demo 代码 — TaskFlow API 写一个 ETL DAG:
from datetime import datetime
from airflow.decorators import dag, task
@dag(
schedule='0 2 * * *', # 每天 2:00
start_date=datetime(2026, 5, 1),
catchup=False,
tags=['marts'],
)
def daily_orders_pipeline():
@task
def extract_kafka_offsets() -> dict:
# 从 Kafka 拿到昨日终止 offset
return {'orders.v1': 12345678}
@task
def run_spark(offsets: dict) -> str:
# 触发 Spark 作业读 Iceberg + Kafka,写回 Iceberg
from airflow.providers.apache.spark.operators.spark_submit import SparkSubmitOperator
# ... 简化:实际用 Operator 而不是 @task ...
return 'iceberg.marts.fct_orders'
@task
def trigger_dbt(table: str) -> None:
# 触发 dbt run 下游 model
...
offsets = extract_kafka_offsets()
table = run_spark(offsets)
trigger_dbt(table)
daily_orders_pipeline()
调度器扫到这个文件,自动建依赖图:extract → spark → dbt,每天 2:00 跑一次。
AWS Glue Data Catalog · 元数据 service
发展过程 — AWS Glue 2017 年发布,Glue Data Catalog 是其中负责元数据的服务,API 完全兼容 Apache Hive Metastore(这一点很关键,因为它意味着任何 Hive-compatible 引擎都能用 Glue 当 metastore)。Glue 本身还包括 Glue ETL(Spark-based ETL)和 Glue Studio(UI),但实际生产中”用 Glue”基本指 Glue Catalog。
核心设计 — Glue Catalog 是个全托管的 metastore service:
- 存 Database / Table / Partition / Column / Property 元数据
- 不存数据本身,数据仍在 S3
- 通过 IAM + Lake Formation 做细粒度权限
- 与 Athena / EMR / Redshift Spectrum / Databricks / Iceberg / Snowflake(2024 支持)等无缝集成
- Crawler — 扫 S3 路径自动推断 schema 注册到 catalog(适合 ad-hoc 数据)
trade-off:绑 AWS,跨云用得少;但在 AWS 内部是 Iceberg / Delta / Hive 元数据的事实接入点。
用户情况 — AWS 上所有有点规模的数据团队默认用 Glue Catalog 当 metastore;EMR / Athena / Redshift Spectrum 都默认配它。非 AWS 替代:Hive Metastore(老牌,自管)、Project Nessie(Iceberg 原生 catalog,支持 git-like 分支)、Polaris(Snowflake 开源)、Unity Catalog(Databricks 主导,2024 开源)。
Demo 代码 — AWS CLI 注册一张 Iceberg 表(实际场景大多由 Spark / Iceberg writer 自动注册,这里展示底层接口的样子):
cat > table.json <<'EOF'
{
"Name": "fct_orders",
"TableType": "EXTERNAL_TABLE",
"Parameters": {
"table_type": "ICEBERG",
"metadata_location": "s3://my-lakehouse/marts/fct_orders/metadata/00000-xxx.metadata.json"
},
"StorageDescriptor": {
"Location": "s3://my-lakehouse/marts/fct_orders/"
}
}
EOF
aws glue create-table \
--database-name marts \
--table-input file://table.json
写完之后,Athena / Spark / Trino 都能 SELECT * FROM marts.fct_orders 看到这张 Iceberg 表。
DataHub · 数据资产平台
发展过程 — DataHub 由 LinkedIn 内部 WhereHows 项目演化而来,2019 年作为新一代 metadata 平台开源,2020 进 Linux Foundation。Acryl Data(原 LinkedIn DataHub 核心团队)2021 成立做商业化,2023 Series A 估值约 $300M。DataHub 解决的是 “我这张表是谁的、上下游链路是什么、最近改过没、是否符合合规” 这一类元数据 + 治理问题 — 这与 Glue Catalog(只管 schema 注册)是不同层次。
核心设计 — 几个关键抽象:
- Entity — Dataset / Dashboard / Chart / Pipeline / DataJob / DataFlow / MLModel / Tag / Glossary / User / Group …,统一建模
- Aspect — 实体的某个”切面”(schema、ownership、documentation、lineage、deprecation、test results)
- MCE / MCP(Metadata Change Event / Proposal)— 写入元数据的事件协议
- GraphQL API — 上层查询接口;UI 基于 GraphQL 构建
- Push + Pull 双模式 — 既能从外部主动 push(用 Python emitter),也能用 ingestion source 主动 pull(Trino / Snowflake / dbt / Airflow / Kafka 等几十种)
DataHub 的杀手特性是 “列级血缘”(column-level lineage):dbt / Spark 的查询解析后,能精确说出”fct_orders.country 来自 dim_users.country 经过 join 而来”。
用户情况 — LinkedIn(自家)、Saxo Bank、Adevinta、Wolt、Pinterest、字节、Stripe 等。竞品:
- OpenMetadata(Collate 公司)— 2022 开源,后来居上,API / UI 更现代
- Amundsen(Lyft 开源,2019)— 较早项目但社区动能弱
- Marquez(WeWork 出身,后归 LF AI & Data)— 主打 OpenLineage 标准
- Atlan / Castor / Select Star / Sifflet — 商业 SaaS 数据目录
Demo 代码 — Python emitter 推送一个 Dataset:
from datahub.emitter.mce_builder import make_dataset_urn
from datahub.emitter.rest_emitter import DatahubRestEmitter
from datahub.metadata.schema_classes import (
DatasetPropertiesClass, OwnershipClass, OwnerClass, OwnershipTypeClass,
)
from datahub.emitter.mcp import MetadataChangeProposalWrapper
emitter = DatahubRestEmitter(gms_server='http://datahub-gms:8080')
urn = make_dataset_urn(platform='iceberg', name='marts.fct_orders', env='PROD')
mcp = MetadataChangeProposalWrapper(
entityUrn=urn,
aspect=DatasetPropertiesClass(
description='每日订单事实表,粒度 (day, country, product_id)',
customProperties={'owner_team': 'commerce-data'},
),
)
emitter.emit(mcp)
mcp2 = MetadataChangeProposalWrapper(
entityUrn=urn,
aspect=OwnershipClass(owners=[
OwnerClass(
owner='urn:li:corpuser:frank',
type=OwnershipTypeClass.DATAOWNER,
)
]),
)
emitter.emit(mcp2)
写入之后,DataHub UI 上 marts.fct_orders 就有了描述、owner、tag,链路自动从 dbt / Airflow 元数据里抓上下游。
数据流时序 — 写入路径 · 读取路径
架构图只画了”哪些组件在哪一层”,但漏掉了”数据实际是怎么从一端流到另一端的”。下面这张图把同一个事务(一笔订单)从产生到被消费的整条路径画出来:上半部是两条并行的写入链路(实时 / 批量),中间是 ClickHouse + Iceberg marts 两个共享枢纽,下半部是从枢纽分发出去的三类读取路径(API / BI / ML)。
读这张图的几个要点:
- 写入路径有两个并行入口:CDC(Postgres → Debezium → Kafka)走流式,SaaS(API → Airbyte)走批;两者最终都汇入 Kafka 或 Iceberg。
- 同一份数据流过两个 hub:Flink 把高频聚合实时物化进 ClickHouse(秒级时延);Spark / dbt 把全量历史落进 Iceberg(分钟到小时级)。这不是替代,是并存 — 实时看板查 ClickHouse,深度分析 / ML / Ad-hoc 查 Iceberg。
- 读取路径按消费场景分流:Trino + Superset 给数据分析师 / 业务,后端 API + Redis 给业务系统,Spark MLlib + Model Server 给 ML / AI。
- 横切的两条:Catalog 是”什么数据在哪里”的真相源,Airflow 是”什么时候让什么发生”的节奏源 — 它们不在主路径上但每条主路径都依赖它们。
大厂实践 — Netflix · Uber · LinkedIn · Airbnb · Pinterest · Shopify · Stripe
理论框架要落地,最快的方式是读那些把同一套栈跑到极致的公司工程博客。下面挑了七家在数据基础设施层有持续输出的西方大厂,各取一两篇有代表性的近期博文或论文,逐一拆解他们的栈长什么样、解决了什么独特问题。这一节回答的是:“前面讲的这些组件,真在产线上跑起来的样子。“
Netflix · Iceberg 发源地 + Maestro 编排
Netflix 是 Apache Iceberg 的发源地 — Ryan Blue 与 Daniel Weeks 在 Netflix 内部为解决 Hive 在 S3 上的痛点(LIST 慢、无 ACID、无 schema evolution、无时间旅行)而设计,2018 年开源。今天 Netflix 数据平台的核心组合是 Iceberg + Spark + Trino + Flink + Maestro(自研工作流引擎,2024 年开源)。
最近的代表性博文 Maestro: Netflix’s Workflow Orchestrator 讲述了 Maestro 的设计哲学:水平扩展的无状态微服务 + CockroachDB 持久化,替代上一代单 leader 系统 Meson — 这是”超大规模 + 多语言用户(SQL / Python / Notebook 都要支持)” 倒推出来的架构。配套博文 Incremental Processing using Netflix Maestro and Apache Iceberg 详细讲述了 Maestro 怎么和 Iceberg 配合做增量物化。
对中国读者的启发:Netflix 选 Iceberg 而不是 Delta 的根本原因是 “多引擎中立性” — Spark / Trino / Flink / Presto / Hive / Impala 都要读同一张表。如果你的栈不止一种计算引擎,这是个强信号。
Uber · Hudi 发源地 + 实时数据栈
Uber 是 Apache Hudi 的发源地(Vinoth Chandar 等,2017 开源),也是行业最完整的”流批一体”工业案例。最权威的参考是 SIGMOD 2021 论文 Real-time Data Infrastructure at Uber(Yupeng Fu, Chinmay Soman),系统讲述 Uber 内部 Kafka + Flink + Pinot + Hive + Hudi 的协同 — 从打车订单到供需匹配到风控,几乎所有 trip 数据都在这条链路上跑。
Hudi 的起源博文 Hudi: Uber Engineering’s Incremental Processing Framework on Apache Hadoop 讲清楚 Hudi 要解决的痛点:大表上的 upsert,Hive 时代靠”全量重写过去 N 天分区”,Hudi 用 ACID + 索引 + 增量消费 三件套替换掉。
对中国读者的启发:Uber 的栈是国内打车 / 即时零售 / 供需匹配类业务最值得对照的模板 — Flink + Pinot 跑亚秒级实时决策,Hive + Hudi 跑离线建模,Kafka 是两者共同的事件源,而不是两套独立链路。
LinkedIn · Kafka 发源地 + DataHub
LinkedIn 是 Apache Kafka 的发源地(Jay Kreps、Neha Narkhede、Jun Rao,2010),也是 DataHub、Pinot、Samza、Voldemort 的源头。整套”以日志为中心”的数据架构哲学,源头是 Jay Kreps 2013 年那篇被引千次的长文 The Log: What every software engineer should know about real-time data’s unifying abstraction — 把”日志”提炼为数据库、分布式系统、数据集成三件事的统一抽象。这篇文章是数据工程师的”必读经典”,看完之后你会理解为什么 Kafka 不只是个消息队列。
2020 年 LinkedIn 把内部元数据平台开源:Open sourcing DataHub: LinkedIn’s metadata search and discovery platform — 今天大部分企业的元数据 / 血缘 / 数据治理参考,都是从这套架构演化来的。
对中国读者的启发:LinkedIn 的设计哲学是 “事件流是真相,数据库是物化视图” — 这是 CDC + 流处理范式的思想根基。
Airbnb · Airflow + Superset + Minerva
Airbnb 是 Maxime Beauchemin 同时孵化出 Airflow + Superset 的母舰 — 这两个项目今天分别是工作流编排与 BI 的开源事实标准。Airflow: a workflow management platform(2015)是工作流编排领域的奠基性文章 — 这之前业界都在写 XML / YAML DAG,Airflow 第一次把”DAG 就是 Python 代码”立成了标准。
更近的 How Airbnb achieved metric consistency at scale(2021)讲述了内部”指标层” Minerva — 12,000+ 指标、4,000+ 维度在一个单一事实源上一致;底层是 Airflow + Hive + Spark + Presto + Druid。Minerva 的概念后来催生了 dbt Semantic Layer、Cube.js 等指标层产品。
对中国读者的启发:Airbnb 案例最大的教益是 “指标定义是数据架构的一等公民” — 不要让同一个 KPI 在十张 dashboard 里有十个 SQL 实现,这是中型团队最容易踩的坑。
Pinterest · 500 PB 数据湖 + Spinner 编排
Pinterest 是大规模 Iceberg 用户(2025 年 AWS re:Invent 披露 500 PB+ 数据湖、10 万+ 张表),并自研了 Airflow 替代品 Spinner。Spinner: Pinterest’s Workflow Platform(2022)讲述了从旧调度器 Pinball 迁移到基于 Airflow + Kubernetes 的 Spinner 的过程,承载 4,000+ 工作流、日均 10,000 流执行、38,000 任务。
2026 年初的新一代入湖框架 Next Generation DB Ingestion at Pinterest 是更近期的实践:Debezium / TiCDC + Kafka + Flink + Spark + Iceberg 的统一 CDC 入湖框架,在线 OLTP 到离线湖仓的时延从小时级压到分钟级。
对中国读者的启发:Pinterest 是西方公司里业务形态最接近字节 / 小红书的(高频用户互动 + 推荐 + 内容),栈选择的参考价值最大。
Shopify · dbt + BigQuery 标杆
Shopify 是 “轻量数据栈” 路线的典型样本 — 不用 Spark / Flink / Kafka 这类重型组件,完全靠 BigQuery 的计算能力 + dbt 的工程化能力,支撑了上市公司体量。代表博文 How to Build a Production Grade Workflow with SQL Modelling(2020)详细介绍了内部代号 Seamster 的方案:dbt + BigQuery,把数据模型分为 Base / Application-ready / Presentation 三层,200+ 数据科学家协作。
对中国读者的启发:Shopify 是”不需要全栈也能跑出规模”的反例 — 如果你的团队不在 Uber / Netflix 那种规模,这套栈反而比”我也要上 Kafka + Flink”更值得抄。BigQuery 的中国对应是阿里 MaxCompute / 火山引擎 ByteHouse,栈思路类似。
Stripe · Trino + Iceberg 替代 Hive
Stripe 的早期栈代表是 2016 年的 Reproducible research: Stripe’s approach to data science — Jupyter + Hadoop + Scalding + Impala + Redshift 的组合。2023 年 Trino Fest 的演讲 Inspecting Trino on ice 更新了现状:Iceberg 已全面替代 Hive,Trino 作为联邦 SQL 入口;通过 Trino event listener 把每条查询审计写入 PostgreSQL,反向观察 Iceberg 表的真实使用模式。
对中国读者的启发:Stripe 是数据栈持续迭代的样本 — 同一家公司 七年间从 Hadoop+Hive 全面转向了 Iceberg+Trino,验证了 §05 / §06 里讲的湖仓 + 联邦查询路线确实经得起时间考验。
怎么选型 — 按团队规模与业务形态
把这套生态搬进自家组织时,很少有人一上来就铺全 16 个项目。实际选型有几条经验法则:
| 团队 / 阶段 | 最小可用栈 | 关键省略 |
|---|---|---|
| 早期(< 10 人数据团队) | Fivetran / Airbyte + Snowflake/BigQuery + dbt + Metabase | 砍掉 Kafka / Flink / Iceberg / ClickHouse / Airflow(用 dbt Cloud 调度) |
| 中期(10-50 人) | Airbyte + Iceberg + Spark + dbt + Trino + Superset + Airflow | 加进湖仓 + 调度 + 联邦查询;Kafka / Flink 视实时需求决定 |
| 后期(>50 人 + 实时业务) | 全栈:Debezium + Kafka + Flink + Iceberg + ClickHouse + dbt + Trino + Redis + Airflow + DataHub | 治理 / 血缘 / 实时数仓 一个都不能少 |
| AI / 推荐 / 风控 重型 | 上述全栈 + Feature Store(Feast)+ Vector DB(Pinecone/Qdrant)+ Ray | ML 链路成为新主路径 |
几个常见错误:
- 盲目上 Kafka — 没有真正的事件流业务(秒级响应 + 多消费者扇出)时,Kafka 是巨大的运维负担。一天几次的批量同步用 Airbyte / Fivetran 完全够。
- dbt 当 Airflow 用 — dbt 是建模工具,不是 workflow engine。复杂依赖、跨系统编排(触发 Spark + dbt + reverse ETL + Slack 通知)还是需要 Airflow。
- 湖仓 vs 实时数仓 二选一 — 这是错的对立。两个并存是常态:湖仓做”全部”、OLAP 做”热的最近”。
- 元数据 catalog 留到最后 — 等数据团队混乱了再补 catalog,迁移成本极高。第一天就上 Glue / DataHub,哪怕只是注册 schema。
最后一个判断:这套栈的演化方向不是”出现一个项目把所有层都吃掉”,而是 “每一层的边界变模糊”:
- Iceberg + ClickHouse 协同(ClickHouse 24.5+ 原生 read/write Iceberg) → 湖仓 / OLAP 边界模糊
- Snowflake / Databricks 都在做 “lakehouse + AI” 平台 → 计算 / 存储 / 查询 三层垂直整合
- Confluent + Flink + Kafka 的一体化 → Ingestion / Processing 两层合并
- dbt Fusion + Iceberg + Trino → Modeling / Query / Storage 集成更紧
- AI 一层的崛起(Vector DB / Feature Store / Agent runtime)正在数据栈右侧叠加一整列新组件
了解每一层的”为什么存在”,才能在边界变化时知道该砍什么、该留什么。这篇文章是这个判断的起点。
参考资料 — 项目官网 · 大厂博客 · 行业综述
项目官网
- Apache Kafka — 分布式提交日志。kafka.apache.org
- Debezium — 数据库 CDC 框架。debezium.io
- Airbyte — 开源 ELT 连接器。airbyte.com
- Fivetran — 闭源托管 ELT。fivetran.com
- Apache Spark — 分布式批处理 + ML 引擎。spark.apache.org
- Apache Flink — 流原生有状态计算。flink.apache.org
- dbt — 数仓内 SQL 建模与工程化。getdbt.com
- Amazon S3 — 对象存储事实标准。aws.amazon.com/s3
- Cloudflare R2 — S3 兼容、零 egress 费用。cloudflare.com/developer-platform/r2
- Apache Iceberg — 开放表格式。iceberg.apache.org
- Delta Lake — Iceberg 同位竞品(Databricks 主导)。delta.io
- Apache Hudi — Iceberg 同位竞品(Uber 主导)。hudi.apache.org
- ClickHouse — 列存实时 OLAP。clickhouse.com
- Trino — MPP 联邦 SQL 引擎。trino.io
- Redis — in-memory 数据结构存储。redis.io
- Valkey — Redis 在 2024 license 变更后的 Linux Foundation fork。valkey.io
- Apache Superset — 开源 BI 与数据探索。superset.apache.org
- Metabase — 自服务 BI。metabase.com
- Apache Airflow — 工作流编排。airflow.apache.org
- Dagster / Prefect — Airflow 同位替代。dagster.io · prefect.io
- AWS Glue Data Catalog — 元数据 service。aws.amazon.com/glue
- DataHub — 数据资产 + 血缘 + 治理平台。datahubproject.io
- OpenMetadata — DataHub 同位替代。open-metadata.org
商业母舰
- Confluent(Kafka)— Jay Kreps、Neha Narkhede、Jun Rao 2014 创立。confluent.io
- Databricks(Spark)— Matei Zaharia 等 2013 创立,2024 估值 $62B。databricks.com
- Astronomer(Airflow)— 2022 估值 $1.7B。astronomer.io
- dbt Labs(dbt)— Tristan Handy 2016 在 Fishtown Analytics 创立,2022 估值 $4.2B。getdbt.com
- Starburst(Trino)— Martin Traverso 等 Trino 创始团队 2018 创立。starburst.io
- Acryl Data(DataHub)— LinkedIn DataHub 核心团队 2021 创立。acryldata.io
- Preset(Superset)— Maxime Beauchemin 2019 创立。preset.io
- Snowflake 收购 Tabular(Iceberg 主商业实体,2024,$1B+)。snowflake.com 公告
大厂博客与论文
- Jay Kreps, “The Log: What every software engineer should know about real-time data’s unifying abstraction”(LinkedIn Engineering, 2013)— Kafka / 流处理范式的奠基长文。engineering.linkedin.com
- Maxime Beauchemin, “Airflow: a workflow management platform”(Airbnb Engineering, 2015)— Airflow 公开发布原贴。medium.com/airbnb-engineering
- Vinoth Chandar & Prasanna Rajaperumal, “Hudi: Uber Engineering’s Incremental Processing Framework on Apache Hadoop”(Uber, 2017)— Hudi 起源博文。uber.com/blog/hoodie
- Kerem Sahin, Mars Lan, Shirshanka Das, “Open sourcing DataHub: LinkedIn’s metadata search and discovery platform”(LinkedIn, 2020-02)— DataHub 开源。linkedin.com/blog/engineering
- Michelle Ark & Chris Wu, “How to Build a Production Grade Workflow with SQL Modelling”(Shopify Engineering, 2020-11)— dbt + BigQuery 三层建模 (Seamster)。shopify.engineering
- Robert Chang et al., “How Airbnb achieved metric consistency at scale”(Airbnb Engineering, 2021-04)— Minerva 指标层第一篇。medium.com/airbnb-engineering
- Yupeng Fu & Chinmay Soman, “Real-time Data Infrastructure at Uber”(SIGMOD 2021)— Uber 实时栈系统论文(Kafka + Flink + Pinot + Hudi)。arxiv.org/abs/2104.00087
- Ace Haidrey et al., “Spinner: Pinterest’s Workflow Platform”(Pinterest Engineering, 2022-02)— Airflow + K8s 自研编排。medium.com/pinterest-engineering
- Kevin Liu, “Inspecting Trino on ice”(Trino Fest 2023, Stripe)— Iceberg + Trino 替代 Hive 的工业案例。trino.io/blog
- Jun He et al., “Maestro: Netflix’s Workflow Orchestrator”(Netflix Tech Blog)— 水平扩展 + CockroachDB 替代 Meson。netflixtechblog.com
- “Incremental Processing using Netflix Maestro and Apache Iceberg”(Netflix Tech Blog)— Maestro + Iceberg 增量物化。netflixtechblog.com
- Liang Mou et al., “Next Generation DB Ingestion at Pinterest”(Pinterest Engineering, 2026-02)— Debezium / TiCDC + Kafka + Flink + Iceberg CDC 入湖。medium.com/pinterest-engineering
- Dan Frank, “Reproducible research: Stripe’s approach to data science”(Stripe Blog, 2016)— 早期数据栈 + 可复现性。stripe.com/blog
行业综述与对比
- “Apache Hudi vs Delta Lake vs Apache Iceberg: Lakehouse Feature Comparison”(Onehouse)— 三家开放表格式深度对比,中文社区高频引用。onehouse.ai/blog
- Netflix Tech Blog — 数据基础设施持续更新。netflixtechblog.com
- Uber Engineering Blog — Hudi / Pinot / Flink 一手案例。uber.com/blog/engineering
- LinkedIn Engineering Blog。engineering.linkedin.com
- Airbnb Engineering Blog。medium.com/airbnb-engineering
- Pinterest Engineering Blog。medium.com/pinterest-engineering
- Databricks Blog — 湖仓 / AI 平台一线视角。databricks.com/blog
- Confluent Blog — Kafka / Flink / 事件驱动架构。confluent.io/blog