订阅更新

Flink SQL Changelog 是什么?

面试问 169 约 2 分钟读完 3 次阅读

本文目录
  1. 面试怎么回答
  2. 动态表不是一次性结果集
  3. 四种 RowKind 表达什么
  4. 为什么主键很关键
  5. Sink 必须接受查询产生的变更模式
  6. 一个典型场景
  7. 参考资料

面试怎么回答

Flink SQL 把流式查询看成持续变化的动态表,Changelog 用 +I、-U、+U、-D 表示插入、更新前、更新后和删除。过滤类查询可能是 Append,聚合、去重、TopN 常产生 Upsert 或 Retract。落地前要判断查询的 Changelog Mode、定义可靠主键,并确认 Sink 是否支持对应更新和删除语义。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

一条 GROUP BY SQL 跑得好好的,换了一个只支持追加写的 Sink 就失败了。

原因不是聚合不能流式算,而是结果会更新,Sink 却只接受新增。

流式 SQL 的聚合、Join 和去重会持续修改动态表,Changelog 用 RowKind 把这些变化编码成消息。


动态表不是一次性结果集

流式表会随着输入事件持续更新。简单过滤可以只追加新行,但 GROUP BY、去重、TopN 和部分 Join 会修改此前已经输出的结果。Changelog 把表的变化编码为事件,使下游能逐步维护同一张逻辑表。

四种 RowKind 表达什么

+I 表示插入,-D 表示删除,-U 和 +U 分别表示更新前与更新后。不同算子和规划可能输出不同组合。Upsert 模式通常依靠主键只发送新值和删除;Retract 模式则显式撤回旧值再加入新值。

四种 RowKind 如何修改动态表

为什么主键很关键

下游要把一次更新作用到正确记录上,必须能识别同一逻辑行。声明不强制校验的主键,会给优化器和 Connector 提供唯一性信息,但数据本身仍要满足约束。没有可靠主键时,下游可能只能按完整旧行撤回,或者根本无法接受更新。

Sink 必须接受查询产生的变更模式

Append-only 文件 Sink 适合只产生 +I 的查询。Upsert Kafka、支持主键更新的数据库或 Lakehouse Connector 可以接收相应更新。Connector 会声明自己支持的 Changelog Mode;如果查询需要更新或删除而 Sink 不支持,规划阶段就可能失败。

查询结果与 Sink 能力必须匹配

一个典型场景

按 user_id 实时统计累计消费。第一笔订单产生 +I,后续订单到达时累计金额改变,结果需要更新旧值。若写入普通追加 Topic,下游会看到同一用户多行;若定义可靠主键并使用 Upsert Sink,下游可以按 key 覆盖成最新结果。

参考资料

刷题进度保存在当前浏览器