有界与无界数据
有界数据(Bounded)有明确的起点和终点,例如一天的分区、一个日志文件,批处理器一次读完全部即可给出结果。无界数据(Unbounded)持续追加、没有终点,例如消息队列里的事件流,流处理器只能依靠窗口、水位线与增量状态持续产出结果,永远等不到「全部到齐」。
同一段逻辑的两种执行
批流一体引擎把两者统一起来:同一段聚合 SQL,作用在有界表上就是一次性作业,作用在无界流上就是常驻作业。判断一个任务的形态,第一步是看它的输入是否有界——这决定了它该由调度器触发还是作为常驻作业运行。
基本信息
| 有界 Bounded | 起止明确,如一天的日志文件、一个数据分区 |
|---|---|
| 无界 Unbounded | 持续追加、无终点,如消息队列事件流 |
| 同一逻辑 | 同一段聚合 SQL 可分别跑在有界表与无界流上 |
| 运行方式 | 有界任务由调度触发;无界任务常驻并需要监控 |
| 监控口径 | 有界看成功与耗时;无界看延迟与积压 |
两种数据的差别
| 对比项 | 有界数据 | 无界数据 |
|---|---|---|
| 终点 | 明确,读完即结束 | 没有终点,持续到达 |
| 全局操作 | 可做全局排序与全量聚合 | 只能按窗口或增量算子近似 |
| 失败重跑 | 改分区重跑即可 | 需重置位点或从快照重放 |
| 结果确定性 | 同一输入结果稳定 | 取决于时间语义与水位线 |
| 监控方式 | 成功与否、耗时 | 延迟、积压、状态大小 |
典型使用场景
- 日终报表:输入是当天分区,属有界数据,用调度跑批最稳妥
- 实时看板:输入是持续事件流,属无界数据,必须常驻运行
- 历史回灌:把历史数据当有界输入处理,不要塞进常驻流作业
- 统一逻辑:同一套 SQL 分别跑批与跑流,口径自然对齐
- 判断任务形态:先看输入是否有界,再决定部署方式与监控指标
Flink SQL:同一聚合的两种数据源
Flink SQL:同一聚合的两种数据源
-- 有界:读取文件或已结束的分区,批模式一次算完
SELECT region, SUM(amount) AS amt
FROM orders_file
GROUP BY region;
-- 无界:读取 Kafka 事件流,必须按窗口持续产出,不能等数据到齐
SELECT TUMBLE_START(ts, INTERVAL '1' MINUTE) AS w, region, SUM(amount) AS amt
FROM orders_kafka
GROUP BY TUMBLE(ts, INTERVAL '1' MINUTE), region;无界数据没有「跑完」的概念:任务成功状态不代表数据是新的。对无界任务的监控要盯住消费延迟与队列积压,而不是任务是否处于运行中。
把无界流当有界表写「等数据到齐再算」的逻辑,会得到永远不触发的下游:窗口依赖水位线推进,而水位线又依赖数据不再迟到,逻辑上一开始就冲突。