Flink多流Join与双流Join实现方案
请介绍Flink中多流Join和双流Join的多种实现方式(Window Join/Interval Join/Regular Join/Lookup Join),对比各自的适用场景和特点。
回答
小字辈
1. Window Join(窗口Join):
- 语法:
stream1.join(stream2).where(...).equalTo(...).window(TumblingEventTimeWindows.of(...)) - 原理:两流在相同窗口内匹配,未匹配的记录丢弃
- 适用:两流在同一时间窗口内关联
- 注意:要求两流有相同的Key和窗口
2. Interval Join(时间区间Join):
- 语法:
stream1.keyBy(...).intervalJoin(stream2.keyBy(...)).between(Time.hours(-1), Time.hours(1)) - 原理:一条流的每条记录与另一条流在指定时间范围内的记录关联
- 适用:订单流关联支付流(支付时间在订单后1小时内)
- 注意:依赖状态存储,状态大小=时间范围×数据量
3. Regular Join(普通Join/双流Join):
- 语法:
table1.join(table2).where(...).equalTo(...)(Table API/SQL) - 原理:基于状态的等值Join,左流和右流的每条记录都会触发处理
- 类型:INNER/LEFT/RIGHT/FULL OUTER Join
- 适用:实时维表关联、流与流的持续关联
- 注意:状态永久保留(需配置TTL),可能导致OOM
4. Lookup Join(维表Join):
- 语法:
FROM stream JOIN dim_table FOR SYSTEM_TIME AS OF ... - 原理:流中每条记录实时查询外部存储(Redis/MySQL/HBase)
- 适用:实时流关联缓慢变化的维度表
- 注意:需要外部存储支持高并发查询
选择建议:
- 有明确窗口边界→Window Join
- 时间偏移关联→Interval Join
- 实时持续双向关联→Regular Join + TTL
- 维表关联→Lookup Join + 缓存