实时数仓技术选型:Kafka、Flink、Spark Streaming、Paimon 核心组件介绍

做实时数仓,选型是第一步,也是最容易踩坑的一步。

我记得刚带团队做第一个实时项目时,大家争论最多的就是「用 Flink 还是 Spark Streaming」。后来踩了不少坑,才慢慢摸清楚每个组件的脾气。今天我就把这四个核心组件——Kafka、Flink、Spark Streaming、Paimon——掰开揉碎讲清楚。

一句话总结:Kafka 是管道,Flink 是引擎,Paimon 是底座,Spark Streaming 是备选。但实际落地远没这么简单。

2.1 Apache Kafka:实时数仓的「中枢神经」

Kafka 在实时数仓里扮演什么角色?说白了,它就是所有数据的「集散地」。业务日志、数据库 CDC、埋点数据……统统先往 Kafka 里塞。

我个人的选型习惯:只要实时链路超过 3 个环节,Kafka 就是必选项。为什么?因为它解耦。

  • 高吞吐:单机每秒几十万条消息,我见过最大的集群撑到百万级 TPS
  • 持久化:消息落盘,可以回溯。我曾经靠这个特性救了两次数据回溯的命
  • 分区机制:并行消费的基础,也是保证顺序的关键

避坑指南:我曾经把 Kafka 的 retention 设得太短(1 天),结果凌晨数据管道出问题,等早上发现时数据已经没了。现在我的习惯是:核心 Topic 至少保留 3 天,配合 Compact 策略。

Kafka 在实时数仓里的典型用法:

# 生产者:模拟实时订单数据
kafka-console-producer.sh \
  --broker-list kafka1:9092,kafka2:9092 \
  --topic ods_order \
  --property parse.key=true \
  --property key.separator=:

# 消费者:Flink 或 Spark 直接消费
kafka-console-consumer.sh \
  --bootstrap-server kafka1:9092 \
  --topic ods_order \
  --from-beginning

2.2 Apache Flink:实时计算的「主力军」

Flink 是我目前在实时数仓项目里的首选计算引擎。为什么?因为它把「实时」这件事做到了极致。

核心优势:

  • 真正的流处理:每条数据来了就处理,延迟毫秒级。Spark Streaming 的微批再快也有秒级延迟
  • 精确一次语义:配合 Kafka 和 Paimon,能做到端到端 Exactly-Once。这个在金融场景里是刚需
  • 状态管理:内置 RocksDB 状态后端,TB 级状态不慌

我在项目中遇到过最典型的场景:实时大屏的订单金额聚合。用 Flink 的滚动窗口,10 秒刷新一次,延迟控制在 3 秒以内。

// Flink SQL:实时订单统计
CREATE TABLE orders (
  order_id STRING,
  user_id STRING,
  amount DECIMAL(10,2),
  order_time TIMESTAMP(3),
  WATERMARK FOR order_time AS order_time - INTERVAL '5' SECOND
) WITH (
  'connector' = 'kafka',
  'topic' = 'ods_order',
  'properties.bootstrap.servers' = 'kafka:9092',
  'format' = 'json'
);

-- 10秒滚动窗口聚合
SELECT 
  TUMBLE_START(order_time, INTERVAL '10' SECOND) AS window_start,
  COUNT(*) AS order_count,
  SUM(amount) AS total_amount
FROM orders
GROUP BY TUMBLE(order_time, INTERVAL '10' SECOND);

注意:Flink 的状态大小会随着时间增长。我曾经有个任务跑了两个月,状态涨到 200GB,Checkpoint 一直失败。后来加了增量 Checkpoint 和状态 TTL 才解决。

2.3 Spark Streaming:批流一体的「老将」

Spark Streaming 现在用得少了,但并不是没有价值。我个人的看法是:

  • 适合场景:秒级延迟可接受、已有 Spark 技术栈、批流一体需求
  • 不适合场景:毫秒级延迟、复杂事件处理、超大状态

Spark Streaming 的核心是微批处理。它把流切成一个个小批次,每个批次用 Spark 引擎跑一次。延迟通常在 1-10 秒。

// Spark Structured Streaming:实时订单统计
val ordersDF = spark
  .readStream
  .format("kafka")
  .option("kafka.bootstrap.servers", "kafka:9092")
  .option("subscribe", "ods_order")
  .load()
  .selectExpr("CAST(value AS STRING) as json")
  .select(from_json($"json", schema).as("data"))
  .select("data.*")

val windowedCounts = ordersDF
  .groupBy(window($"order_time", "10 seconds"))
  .agg(
    count("*").as("order_count"),
    sum("amount").as("total_amount")
  )

windowedCounts.writeStream
  .outputMode("complete")
  .format("console")
  .start()
  .awaitTermination()

我的建议:如果团队 Spark 能力强、延迟要求不高,用 Spark Streaming 没问题。但新项目我建议直接上 Flink。

2.4 Apache Paimon:湖仓一体的「新底座」

Paimon 是最近两年才火起来的。它解决了实时数仓里一个老大难问题:流式数据怎么高效入湖。

以前的做法是 Kafka -> Flink -> Hive,但 Hive 的小文件、延迟、ACID 问题让人头疼。Paimon 把 Lakehouse 的存储能力直接拉到了实时层面。

Paimon 的核心能力:

  • 流批一体存储:同一份数据,既能流式写入,又能批量读取
  • LSM 树结构:写入快,适合实时场景
  • 增量读取:Flink 可以直接读 Paimon 的 changelog,实现实时 ETL
  • 表模式演进:加列、改类型,不用重建表
-- Flink SQL 创建 Paimon 表
CREATE CATALOG paimon WITH (
  'type' = 'paimon',
  'warehouse' = 'hdfs://namenode:8020/warehouse'
);

CREATE TABLE paimon.ods.orders (
  order_id STRING,
  user_id STRING,
  amount DECIMAL(10,2),
  order_time TIMESTAMP(3),
  dt STRING,
  PRIMARY KEY (order_id) NOT ENFORCED
) PARTITIONED BY (dt)
WITH (
  'bucket' = '4',
  'changelog-producer' = 'input',
  'snapshot.time-retained' = '3d'
);

实战经验:我最近一个项目用 Paimon 替换了 Hive,实时链路从 Kafka -> Flink -> Hive 变成了 Kafka -> Flink -> Paimon。延迟从分钟级降到了秒级,小文件问题也自动解决了。

2.5 技术选型对比

这四个组件怎么搭?我整理了一张对比表:

维度 Kafka Flink Spark Streaming Paimon
定位 消息管道 流计算引擎 微批计算引擎 湖仓存储
延迟 毫秒级 毫秒级 秒级 秒级(写入)
状态管理 无 强(RocksDB) 弱(依赖外部) 内置 LSM
精确一次 支持 支持 支持 支持
适用场景 数据中转 实时 ETL、大屏 批流一体 实时入湖

2.6 整体架构图

下面这张图是我现在做实时数仓的标准架构。你想想看,数据从产生到落地,每一步都有对应的组件:

实时数仓核心组件架构图 业务数据源 日志/埋点 数据库 CDC Apache Kafka(消息管道) Topic: ods_order, ods_log, cdc_user ... Apache Flink(实时计算引擎) 实时 ETL · 窗口聚合 · 维表关联 · 状态管理 Apache Paimon(湖仓存储) ODS · DWD · DWS · ADS 分层存储 实时大屏 OLAP 查询 数据服务 API 数据源 消息管道 计算引擎 湖仓存储

我的选型建议:新项目直接上 Kafka + Flink + Paimon 三件套。Spark Streaming 留着做批流一体的补充。这套组合我用了两年,稳定性很高。

2.7 选型决策流程

最后,我分享一个选型决策的思路。遇到新项目时,我会问自己三个问题:

  1. 延迟要求多少?毫秒级 → Flink;秒级 → Spark Streaming 也行
  2. 数据要入湖吗?要 → Paimon;不要 → Kafka 直接消费
  3. 团队熟悉什么?Java/ Scala 多 → Flink;Python 多 → Spark