3. 主流增量计算引擎概览

做增量计算选型,说白了就是给数据找一条「最短的延迟路径」。我这些年接触过的引擎少说也有七八个,但真正在生产环境扛过流量的,也就下面这五位。咱们一个一个看,它们各自擅长什么、不擅长什么,心里得有个底。

核心观点:没有最好的引擎,只有最合适的场景。选型前先问自己三个问题——延迟要求多高?状态多大?团队熟悉什么语言?

3.1 Apache Flink — 状态计算的王者

Flink 是我个人用得最多的引擎。它的核心优势就一个词:状态。你想想看,增量计算本质上就是「记住过去,计算现在」。Flink 把状态管理做成了第一等公民,支持 RocksDB 和堆内存两种后端,生产环境里我见过单任务管理 TB 级状态还稳如老狗。

我记得 2020 年帮一家金融客户做实时风控,他们之前用 Spark Streaming 做窗口聚合,状态稍微大一点就 GC 爆炸。换成 Flink 的 RocksDB 状态后端后,问题直接解决。嗯,这里要注意:RocksDB 读写有序列化开销,别把每个事件都搞成大对象。

// Flink 增量聚合示例 — 计算每五分钟的点击量
DataStream<ClickEvent> clicks = env.addSource(new KafkaSource<>(...));

clicks
    .keyBy(ClickEvent::getPageId)
    .window(TumblingProcessingTimeWindows.of(Time.minutes(5)))
    .aggregate(new ClickCountAggregate())
    .addSink(new RedisSink<>(...));

// 自定义聚合函数,增量更新,不保留原始数据
public static class ClickCountAggregate
    implements AggregateFunction<ClickEvent, Long, Long> {
    @Override
    public Long createAccumulator() { return 0L; }
    @Override
    public Long add(ClickEvent event, Long acc) { return acc + 1; }
    @Override
    public Long getResult(Long acc) { return acc; }
    @Override
    public Long merge(Long a, Long b) { return a + b; }
}
我的习惯:Flink 做增量聚合时,优先用 AggregateFunction 而不是 ProcessFunction。前者框架帮你做了增量合并,后者你得自己维护状态,容易踩坑。

3.2 Apache Spark Streaming — 微批的老牌劲旅

Spark Streaming 走的是微批路线,把连续流切成一个个小批次。好处是跟 Spark 生态无缝衔接,坏处是延迟下限受批次间隔限制。我曾经在 2018 年用 Spark Streaming 做日志 ETL,批次间隔设到 500ms 就是极限了,再小反而吞吐下降。

后来 Spark 推出了 Structured Streaming,引入了连续处理模式(Continuous Processing),理论上延迟能降到毫秒级。但我实际测试下来,连续模式的状态一致性还不如微批模式成熟。所以我的建议是:如果延迟容忍度在秒级以上,Spark Streaming 依然是个稳妥的选择,尤其是你已经有了 Spark 技术栈。

对比维度 Flink Spark Streaming
处理模型 逐条处理(真流) 微批(伪流)
端到端延迟 毫秒级 秒级(微批)
状态管理 原生支持,TB 级 依赖外部存储
SQL 支持 Table API / SQL Structured Streaming SQL
适用场景 实时风控、CDC 日志 ETL、报表

3.3 Kafka Streams — 轻量级库的优雅

Kafka Streams 不是框架,是一个 Java 库。你把它打成 jar 包,想跑哪跑哪。它的增量计算模型基于 Kafka 的日志压缩和 KTable 概念,天然支持「变更数据捕获」的语义。

我去年做一个用户画像实时更新项目,数据源就是 Kafka 里的用户行为日志。用 Kafka Streams 的 KTable 做增量聚合,代码量只有 Flink 版本的三分之一。为什么?因为 Kafka Streams 把状态存储和容灾都委托给了 Kafka 本身,你不用额外维护状态后端。

避坑指南:我曾经在生产环境遇到过 Kafka Streams 的 rebalance 风暴。当任务拓扑复杂、分区数多时,一次 consumer 重启可能触发全量 rebalance,导致几分钟的延迟毛刺。解决方案是给每个实例分配固定分区,或者用 Static Group Membership。
// Kafka Streams 增量聚合 — 按用户统计订单金额
KStream<String, Order> orders = builder.stream("orders");

KTable<String, Double> totalByUser = orders
    .groupByKey()
    .aggregate(
        () -> 0.0,
        (key, order, total) -> total + order.getAmount(),
        Materialized.<String, Double, KeyValueStore<Bytes, byte[]>>as("total-store")
            .withValueSerde(Serdes.Double())
    );

totalByUser.toStream().to("user-totals");

3.4 RisingWave — 云原生的流数据库

RisingWave 是近几年冒出来的新秀。它的定位很明确:用 SQL 做实时增量计算。你不需要写 Java 或 Scala,直接写 CREATE MATERIALIZED VIEW 就能定义一个持续更新的增量视图。

我试用 RisingWave 做 IoT 设备数据的实时聚合时,最大的感受是「爽」。以前用 Flink 写一个滑动窗口聚合,得调 watermark、allowedLateness、sideOutput 一堆参数。在 RisingWave 里,一条 SQL 搞定。它的内部引擎会自动把 SQL 翻译成增量计算计划,并且支持 Exactly-Once 语义。

-- RisingWave 增量物化视图 — 每分钟设备平均温度
CREATE MATERIALIZED VIEW avg_temp_per_min AS
SELECT
    device_id,
    window_start,
    AVG(temperature) AS avg_temp
FROM
    TUMBLE(device_events, event_time, INTERVAL '1' MINUTE)
GROUP BY
    device_id, window_start;
我的观察:RisingWave 目前更适合「查询模式固定」的场景。如果你的增量计算逻辑频繁变动,每次都要重建物化视图,成本不低。它跟 Flink 不是替代关系,而是互补——Flink 做复杂 ETL,RisingWave 做实时 Serving。

3.5 Materialize — 增量视图的先行者

Materialize 和 RisingWave 理念相似,都是「流式物化视图」。但 Materialize 更早提出这个方向,它的核心引擎基于 Timely Dataflow 和 Differential Dataflow,理论上能处理任意复杂的增量计算。

我记得 Materialize 刚开源时,社区里有人用它做实时仪表盘,数据源是 PostgreSQL 的 CDC 流。一条 CREATE MATERIALIZED VIEW 语句,就能让仪表盘每秒刷新一次,延迟在 100ms 以内。不过 Materialize 的资源消耗偏高,同样的计算负载,它比 Flink 多吃 30%-50% 的内存。

-- Materialize 增量物化视图 — 实时订单统计
CREATE MATERIALIZED VIEW order_stats AS
SELECT
    status,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM
    orders
GROUP BY
    status;
选型速查表:
  • 需要毫秒级延迟 + 复杂状态 → Flink
  • 已有 Spark 生态 + 秒级容忍 → Spark Streaming
  • 轻量级 + Kafka 原生 → Kafka Streams
  • 纯 SQL + 云原生 → RisingWave
  • CDC + 实时物化视图 → Materialize
增量计算引擎选型全景图 数据源 计算引擎层 Apache Flink 真流 · 状态管理 Spark Streaming 微批 · 生态兼容 Kafka Streams 轻量库 · 日志压缩 RisingWave SQL · 云原生 Materialize 物化视图 · CDC 输出目标 消息队列 数据库 实时仪表盘 数据湖 API 服务

这五个引擎,每个都有自己的「脾气」。Flink 适合复杂状态计算,Spark Streaming 适合已有生态的团队,Kafka Streams 适合轻量级场景,RisingWave 和 Materialize 则代表了「SQL 化增量计算」的新趋势。选型时别只看技术参数,团队的技术栈和运维能力往往才是决定因素。