1、孙梦瑶/美团开发工程师Flink 流式 Join 算子优化Optimizations on Flink Streaming Join OperatorsJoin 算子现有实现和问题#1Regular Join mini-batch 优化#2Interval Join 1 对 N 关联优化#3Join 算子优化的落地与实践#4#1Join 算子现有实现和问题为什么需要 Join 算子 事物之间存在关联 聚合计算分析时关注事物间的关联 数据对事物的描述是简化后的,存在缺陷的存在关联事物,其属性各自存储在自己的表里4订单退款曝光点击为什么 Join 算子在流计算中备受关注 批计算、关系型数据库中是怎
2、么进行 Join 运算的Nested Loop JoinSort Merge JoinHash Join 流计算最大的特点:无界跟我关联的那条数据,它什么时候来?它到底来不来了?Outer Join 场景它不来我还得补 null 下发它还有没有兄弟还没来?5基于两侧或其中一侧的全集进行运算在无界流上都用不了1231312313?6常见流式 Join 算子实现 最直观的想法,无界变有界:Window Join利用 Flink 时间窗口机制只考虑在同一个时间窗口内的数据进行关联 存在的问题窗口边界上的数据关联失败10:59 的曝光,11:01 的点击,互相关联不上时效性差,窗口结束才触发计算和下发
3、Outer Join 场景下对时效性和准确性的权衡1231310:0011:0012:007常见流式 Join 算子实现 准确性优先:Interval Join利用 Flink 的 Watermark 机制当前侧的点,关联对侧的时间区间 存在的问题时效性较差,Outer 补 null 的数据要等区间结束才下发状态过期逻辑需额外处理(在过期时补 null 下发)Outer Join 场景下对时效性和准确性的权衡123138常见流式 Join 算子实现 时效性优先:Regular Join(Streaming Join)利用 Flink Table 的回撤重发机制每条数据与对侧当前已到达的所有数据
4、关联得到的都是“当下”的正确结果 存在的问题“准确”是暂时的,下发的并不是最终结果回撤重发机制导致数据量放大依赖全局的状态清理策略(TTL)Outer Join 场景下对时效性和准确性的权衡123139流式 Join 算子的出路 没有完美方案 不同场景下需要做不同取舍 不同的取舍下有不同的优化方案时效性好准确性好使用方便实现简洁支持回撤流三种流式 Join 实现对比Window JoinInterval JoinRegular Join#2Regular Join mini-batch 优化11Regular Join 造成数据量放大和不准确 一个 Outer Join 发生数据回撤的例子SE
5、LECTT3.id AS id3,T1.txt AS txt1,T2.txt AS txt2,T3.txt AS txt3FROM T3LEFT JOIN(SELECT*FROM(SELECT id,MAX(ts)AS ts,LAST_VALUE(txt)AS txt FROM T1 GROUP BY id)AS T1 LEFT JOIN(SELECT id,MAX(ts)AS ts,LAST_VALUE(txt)AS txt FROM T2 GROUP BY id)AS T2 ON T1.id=T2.id)AS T1 ON T3.id=T1.id12Regular Join 造成数据量放大和
6、不准确 一个 Outer Join 发生数据回撤的例子T1(group by id去重)T3T2(group by id去重)临时表结果表Left Join on T1.id=T2.idLeft Join on T3.id=T1.id13Regular Join 造成数据量放大和不准确 一个 Outer Join 发生数据回撤的例子Left Outer Join 右流发生更新一次更新下发8条数据,数据量放大其中还有短暂的错误数据“+A,null,null”“+A,L,null”T1T2T3临时表结果表+L+L,null+R-L,null+L,R+A+A,L,R-R-L,R-A,L,R+A,nu