Flink Joins(SQL篇)
(TODO)
双流 Join(Regular Join)
1 | SELECT * |
要点:
- 支持
INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN; - 仅支持等值连接条件;
- 为了计算查询结果,需要将左右两端的流都持久性保持在状态中,因此中间状态可能会无限增长,这具体取决于两端输入表中的distinct行数和中间连接结果中的distinct行数;
- 配置状态TTL防止状态无限增长;
区间 Join(Interval Join)
1 | SELECT * |
要点:
- 区间连接需要至少有一个“等值连接条件”,以及一个限定两端时间的连接条件;
- 支持
INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN; - 输入表必须是有时间属性的append-only表,支持Processing Time和Event Time;
- 左右流都会触发结果更新;
- State 自动清理,根据时间区间保留数据;
- 输出流保留时间属性;
区间Join中的连接条件
Interval Join中需要有连接条件对两端的流进行限制。可以使用:
- 区间的形式:使用
<、<=、>=、>或使用BETWEEN ... AND ...; - 或在两端表的相同类型的时间属性(例如,处理时间或事件时间)使用等值连接条件;
以下示例都是合法的区间连接条件:
ltime = rtimeltime >= rtime AND ltime < rtime + INTERVAL '10' MINUTEltime BETWEEN rtime - INTERVAL '10' SECOND AND rtime + INTERVAL '5' SECOND
下面我们来分析一下Interval Join中的连接条件是如何限制两端状态的。如图,我们的业务场景是:对订单流和配送流进行连接,约束为:收到订单4小时以内进行配送的订单。
- 左图,当订单流中的watermark到达10:15,为了满足约束条件,配送状态只需要保持配送时间在10:15~14:15范围之内的数据,10:15是配送状态的下限,所以配送时间在10:15之前的配送状态都可以不再维护,这样就定义了配送流的下限;
- 右图,当配送流中的watermark到达12:00,为了满足约束条件,订单状态只需要保持下单时间在8:00~12:00范围之内的数据,8:00是订单状态的下限,所以下单时间在8:00之前的配送状态都可以不再维护,这样就定义了订单流的下限;
时态表Join(Temporal Join)
参考
- 基于 Flink 的典型 ETL 场景实现
- 基于 FLINK SQL 的实时数据打宽,PPT链接,演示代码链接
- https://nightlies.apache.org/flink/flink-docs-release-1.13/zh/docs/dev/datastream/operators/joining/
- https://nightlies.apache.org/flink/flink-docs-release-1.13/zh/docs/dev/table/sql/queries/joins/
- https://www.slideshare.net/FlinkForward/flink-forward-san-francisco-2019-how-to-join-two-data-streams-piotr-nowojski