流、表与“二元性”的幻象

本文涉及的产品
实时计算 Flink 版,1000CU*H 3个月
简介: 本文探讨流与表的“二元性”本质,指出实现该特性需具备主键、变更日志语义和物化能力。强调Kafka与Iceberg因缺乏更新语义和主键支持,无法真正实现二元性,唯有统一系统如Flink、Paimon或Fluss才能无缝融合流与表。

本文由 Ververica 首席架构师 Giannis Polyzos 撰写,__探讨了流与表的“二元性”本质,澄清常见误解,指出 Kafka 与 Iceberg 等系统在缺乏主键和变更语义时无法真正实现该二元性,并强调统一系统对流表融合的重要性。


什么是流/表二元性?

核心思想其实很简单:

  • 流(Stream) 是一个永不停止的变更日志 📜。

  • 表(Table) 是这些变更的物化视图,即当前状态 🗄️。

👉 任何表都可以表示为一个更新流。 👉 任何更新流也可以物化成一张表。

举个例子:

  • 数据库发出 INSERT、UPDATE 和 DELETE 事件 → 这就是一个

  • 按顺序应用这些事件,就能重建出原始的

  • 反过来,捕获表的每一次变更 → 就能得到变更日志流(changelog stream)。

这就是双向映射,也就是所谓的“二元性”💡。

二元性的核心前提

要让这种“魔法”成立,必须满足以下条件:

  • 变更日志语义(Changelog semantics):流不仅要包含新增记录,还必须携带更新(UPDATE)和删除(DELETE)操作。

  • 主键(Primary keys):系统需要知道要更新哪一行。

  • 时间是一等公民:流提供事件的顺序,表则代表“在时间 T 的状态”。

  • 物化能力(Materialization):表本质上是流的一个物化视图。

  • 一致性(Consistency):重放相同的流,始终能得到相同的表。

二元性何时会失效?

事情有趣的地方就在这里。当前社区中,很多人试图将 Apache KafkaApache Iceberg 的集成描述为“流/表二元性”,但事实并非如此。我们来拆解一下:

Apache Iceberg

Iceberg 是一个优秀的开源表格式,特别适合管理仅追加(append-only) 的数据。

但请注意:

  • 不强制要求主键

  • 原生不支持流式场景下的行级更新或删除

这意味着你无法获得真正的流/表二元性——你只能拿到一系列快照(snapshots),而不是持续演化的状态。

Apache Kafka

Kafka 本质上是一个事件日志(event log)不是变更日志(changelog)

默认情况下:

  • 它只存储原始事件;

  • 没有更新或删除的概念

所以:

  • Kafka 本身 ≠ changelog 流

不过……

借助 Debezium 或 Flink CDC

  • 你可以从数据库捕获真正的变更事件(包含主键和操作类型);

  • Kafka Topic 此时才真正承载了变更日志流

  • Flink 等引擎就能基于这些流物化出表。

关键点:Kafka 本身不是 changelog,这点必须强调,因为这直接影响下游处理的复杂度。

像 Apache Flink 这样的流处理引擎,其核心正是建立在 changelog 模型之上的。

由于 Kafka 不原生提供 changelog,Flink 必须引入一个昂贵的算子(如 ChangelogNormalize)来对 Kafka 数据进行归一化处理——这会导致:

  • 状态膨胀

  • 冗余存储

更糟糕的是,这个归一化后的 changelog 无法复用。 如果你有多个作业消费同一个 Kafka Topic,每个作业都得各自重建并存储一份 changelog 状态

那么,流和表必须在同一个系统里吗?

这是我一直在思考的问题。

确实,很多系统天然支持流/表二元性,比如:

  • PostgreSQL、MySQL(通过逻辑复制)

  • Apache Beam

  • 以及我深度参与的 Apache Flink、Apache Paimon,还有最近的 Apache Fluss

所以,我倾向于认为:“最好在同一个系统内实现”。

否则,你只是在做两个无法原生支持二元性的系统之间的集成

不过,由于目前尚无“流/表二元性”的正式定义,答案也可以是:不一定

像 Flink、Kafka Streams 等系统,在同一个引擎中同时暴露流和表 API,让二元性变得无缝。 但理论上,你也可以用不同系统实现——只要保证事件顺序、主键和 changelog 语义不丢失,二元性依然成立

但基于前文分析,我认为将 Kafka + Iceberg 的组合称为“流/表二元性”是不严谨的

总结

  • 流 = 故事(所有发生过的事件)

  • 表 = 快照(当前的真实状态)

二者共同构成了现代实时分析、流处理和湖仓一体架构的基石。

但请务必警惕:

  • Kafka ≠ changelog(除非结合 CDC)

  • Iceberg ≠ 表二元性(无主键,仅支持追加)

当然,业界还有更多关于这一话题的演进和不同技术路线,但本文暂且聚焦于此。

PS:如果你正在寻找一个真正基于上述原则构建的系统,并希望获得额外能力(如直接查询流、内置缓存等),不妨关注一下 Apache Fluss

继续奔涌吧 🌊🤘


更多内容


活动推荐

复制下方链接或者扫描二维码
即可快速体验 “一体化的实时数仓联合解决方案”
了解活动详情:https://www.aliyun.com/solution/tech-solution/flink-hologres

相关文章
|
9天前
|
机器人 API 调度
基于 DMS Dify+Notebook+Airflow 实现 Agent 的一站式开发
本文提出“DMS Dify + Notebook + Airflow”三位一体架构,解决 Dify 在代码执行与定时调度上的局限。通过 Notebook 扩展 Python 环境,Airflow实现任务调度,构建可扩展、可运维的企业级智能 Agent 系统,提升大模型应用的工程化能力。
|
人工智能 前端开发 API
前端接入通义千问(Qwen)API:5 分钟实现你的 AI 问答助手
本文介绍如何在5分钟内通过前端接入通义千问(Qwen)API,快速打造一个AI问答助手。涵盖API配置、界面设计、流式响应、历史管理、错误重试等核心功能,并提供安全与性能优化建议,助你轻松集成智能对话能力到前端应用中。
683 154
|
15天前
|
人工智能 数据可视化 Java
Spring AI Alibaba、Dify、LangGraph 与 LangChain 综合对比分析报告
本报告对比Spring AI Alibaba、Dify、LangGraph与LangChain四大AI开发框架,涵盖架构、性能、生态及适用场景。数据截至2025年10月,基于公开资料分析,实际发展可能随技术演进调整。
960 152
|
负载均衡 Java 微服务
OpenFeign:让微服务调用像本地方法一样简单
OpenFeign是Spring Cloud中声明式微服务调用组件,通过接口注解简化远程调用,支持负载均衡、服务发现、熔断降级、自定义拦截器与编解码,提升微服务间通信开发效率与系统稳定性。
359 156
|
7天前
|
分布式计算 监控 API
DMS Airflow:企业级数据工作流编排平台的专业实践
DMS Airflow 是基于 Apache Airflow 构建的企业级数据工作流编排平台,通过深度集成阿里云 DMS(Data Management Service)系统的各项能力,为数据团队提供了强大的工作流调度、监控和管理能力。本文将从 Airflow 的高级编排能力、DMS 集成的特殊能力,以及 DMS Airflow 的使用示例三个方面,全面介绍 DMS Airflow 的技术架构与实践应用。
|
8天前
|
人工智能 自然语言处理 前端开发
Qoder全栈开发实战指南:开启AI驱动的下一代编程范式
Qoder是阿里巴巴于2025年发布的AI编程平台,首创“智能代理式编程”,支持自然语言驱动的全栈开发。通过仓库级理解、多智能体协同与云端沙箱执行,实现从需求到上线的端到端自动化,大幅提升研发效率,重塑程序员角色,引领AI原生开发新范式。
474 2