双流JOIN:两条流怎么关联到一起
Interval Join · Window Join · Regular Join · State清理
📋 面试题
Flink两条流怎么做JOIN?有哪几种方式?各自的State是怎么管理的?
💡 先想30秒,再往下看答案
为什么双流JOIN难?
离线JOIN:两张表都是完整的,直接关联。 实时JOIN:两条流的数据到达时间不确定。订单流来了一条,用户流里对应的用户数据可能还没来。必须等,但不能无限等。
三种双流JOIN
| 类型 | 原理 | State管理 | 适用场景 |
|---|---|---|---|
| Interval Join | 在时间范围内匹配 | 自动清理过期State | 最常用,推荐 |
| Window Join | 同一窗口内匹配 | 窗口结束自动清理 | 两流时间对齐的场景 |
| Regular Join | 无限等待匹配 | State无限增长(危险) | 必须配TTL |
Interval Join(推荐)
订单流:[order_id, user_id, order_time]
点击流:[click_id, user_id, click_time]
需求:订单前后5分钟内有点击行为的,关联在一起
orderStream.keyBy(o -> o.getUserId())
.intervalJoin(clickStream.keyBy(c -> c.getUserId()))
.between(Time.minutes(-5), Time.minutes(5)) // 前后5分钟
.process(new ProcessJoinFunction<Order, Click, Result>() {
@Override
public void processElement(Order order, Click click, Context ctx, Collector<Result> out) {
out.collect(new Result(order, click));
}
});
时间线:
click_time ---|--------订单时间--------|--- click_time
order_time-5min order_time order_time+5min
只有click_time落在这个范围内才能匹配上
超过范围的数据自动从State中清除 → State不会无限增长
我在广告归因里用Interval Join:用户点击广告后30分钟内的下单行为关联到这次点击。between(-0, Time.minutes(30))——点击之后30分钟内的订单才算归因成功。
Window Join
// 两条流在同一个5分钟窗口内做JOIN
orderStream.join(payStream)
.where(o -> o.getOrderId())
.equalTo(p -> p.getOrderId())
.window(TumblingEventTimeWindows.of(Time.minutes(5)))
.apply(new JoinFunction<Order, Payment, Result>() {
@Override
public Result join(Order order, Payment payment) {
return new Result(order, payment);
}
});
缺点:如果订单在窗口最后1秒到达,支付在下一个窗口第1秒到达,就关联不上。对时间对齐要求高。
Regular Join(Flink SQL)
-- Flink SQL的Regular Join
SELECT o.order_id, o.amount, p.pay_time
FROM orders o
JOIN payments p ON o.order_id = p.order_id;
-- 问题:两条流的State会无限增长!
-- 必须设State TTL
SET 'table.exec.state.ttl' = '1h'; -- 1小时后自动清理
💡 Regular Join是面试陷阱题。 面试官问你Flink SQL两张表JOIN怎么写,很简单。但追问State怎么管理——如果你不提TTL,说明你没在生产用过。
State管理是核心
| JOIN类型 | State大小 | 清理机制 |
|---|---|---|
| Interval Join | 有限(时间范围内) | 超过时间范围自动清理 |
| Window Join | 有限(窗口内) | 窗口结束自动清理 |
| Regular Join | 无限增长 | 必须手动设TTL |
面试加分提示
💡 场景+选型+State管理:
「双流JOIN有三种方式。Interval Join最常用,指定时间范围内匹配,State自动清理。Window Join要求两条流时间对齐。Regular Join最灵活但State无限增长,必须配TTL。
我做广告归因用Interval Join:点击后30分钟内的订单关联到这次点击。State自动清理超过30分钟的数据,不用担心膨胀。」
📌 总结
| 记忆点 | 内容 |
|---|---|
| 核心难点 | 两条流数据到达时间不确定 |
| Interval Join | 指定时间范围匹配,State自动清理(推荐) |
| Window Join | 同窗口匹配,时间对齐要求高 |
| Regular Join | 灵活但State无限增长,必须设TTL |
| 面试关键 | 讲清楚State管理机制 |
▶ 下一篇预告:DAY 17 迟到数据处理
Wood聊大数据 | 9年大数据老兵,聊技术、聊职场、聊成长
小红书正文
双流JOIN是Flink面试高频题,但大部分人只会写SQL不会讲State管理。
三种方式:① Interval Join——指定时间范围匹配,State自动清理(推荐)② Window Join——同窗口匹配,时间对齐要求高 ③ Regular Join——最灵活但State无限增长,必须设TTL。
面试陷阱:Flink SQL两张表JOIN很简单,追问State怎么管理才是关键。不提TTL=没在生产用过。
我做广告归因用Interval Join:点击后30分钟内的订单才算归因。State自动清理过期数据,不会膨胀。