本文源码基于flink 1.14
被同事问到几个关于AsyncIO和lookUp维表的问题所以翻了下源码,从源码的角度解惑这几个问题
对于AsyncIO不了解的可以看看之前写的这篇 《Flink中异步AsyncIO的实现 (源码分析)》
问题一:AsyncIO 有(排序 / 非排序) 模式,非排序模式数据会乱序,那水印waterMarker会乱序吗 ???
不想看源码的先直接给出答案
:不会乱序,接收到水印数据后非排序模式会,直接往下游发送waterMarker
问题二:LookUp维表join分为同步和Async, 上面异步非排序,数据会乱序水印不会,那sql的维表异步join数据会乱序吗 ???
:不会乱序,源码中默认都是AsyncIO的排序(Ordered)模式
ok上源码
问题一:AsyncIO水印会乱序吗?
来看一下异步io对应的StreamOperator的源码 org.apache.flink.streaming.api.operators.async.AsyncWaitOperator
异步io接收到数据以后,加入到queue里面,然后调用用户写的UserFunction
异步io接收到水印以后,同样加入到queue里面
那继续看addToWorkQueue方法接收到水印以后
加入具体的queue
继续,这里只看非排序的unordered
也是一样直接加addWtaermark()
将水印包装成一个WatermarkQueueEntry对象直接放queue
ok那来看下这个watermarkQueueEntry类
可以看到当水印进入queue以后直接就是已完成的了,就可以直接往下游发送,管你其他异步处理的数据完成没完成,水印已经往下发了
问题二:LookUp维表异步join会导致数据乱序吗?
看下关于lookup的calcite的对应规则
调用链不看了,有点长来看最后生成的,execNode物理的relNode执行节点StreamExecLookupJoin
来看下它抽象类 CommonExecLookupJoin的translateToPlanInternal方法
最后走到 createAsyncLookupJoin 来看下如何生成AsyncIO的function的
ok 用的ordered模式的异步io,维表关联的数据尽管是异步去join的,但是往下游发的时候还是按顺序的
不会乱序