CodeWalk

Flink双流Join实现与优化(Regular/Interval/Window Join)

作者:小字辈 · 2026-05-30 12:55

Flink SQL支持三种双流Join:Regular Join(普通Join)、Interval Join(区间Join)、Window Join(窗口Join)。请解释三者的原理差异(生命周期/State清理/输出时机)、适用场景、以及Join相关的状态大小控制与优化策略(TTL配置/RocksDB状态后端调优)。

回答

小字辈

三种双流Join对比

1. Regular Join(普通Join)

SELECT * FROM order_stream o 
JOIN payment_stream p ON o.order_id = p.order_id
  • 原理:左右流各自维护完整State,任意匹配即输出
  • 生命周期:State永久保留(直到TTL过期)
  • 输出:追加(Append)或更新(Update)
  • 问题:State无限增长,需配置TTL

2. Interval Join(区间Join)

SELECT * FROM order_stream o
JOIN payment_stream p
ON o.order_id = p.order_id
AND p.ts BETWEEN o.ts AND o.ts + INTERVAL '5' MINUTE
  • 原理:基于时间窗口约束,只有时间在区间内的数据才Join
  • 生命周期:State只保留窗口时长(5分钟过期)
  • 输出:只输出一次,不会撤回
  • 优点:State可控,适合流表关联

3. Window Join(窗口Join)

SELECT * FROM order_stream o,
TABLE(TUMBLE(TABLE o, DESCRIPTOR(ts), INTERVAL '1' HOUR))
JOIN payment_stream p ON o.order_id = p.order_id
  • 原理:同一窗口内的数据做Join
  • 生命周期:窗口结束时清理State
  • 输出:窗口结束时一次性输出

优化策略

table.exec.state.ttl: 1h     # Regular Join State存活1小时
table.exec.mini-batch.enabled: true
table.exec.mini-batch.size: 5000
state.backend.type: rocksdb  # 大状态用RocksDB
state.backend.rocksdb.memory.managed: true  # 托管内存