借用官网的一个例子:
假设存在一个序列,序列中的元素是具有不同颜色与形状的图形,我们希望在序列里相同颜色的图形中寻找满足一定顺序模式的图形对(比如在红色的图形里,有一个长方形跟着一个三角形)。 同时,我们希望寻找的模式也会随着时间而改变。
在这个例子中,我们定义两个流,一个流包含图形(Item),具有颜色和形状两个属性。另一个流包含特定的规则(Rule),代表希望寻找的模式。
Flink 开发的时候,经常会遇到这种情况,数据的输入源有多个,需要将一些流先关联起来(比如:清洗规则、动态配置),再做后续的计算。
对于这样的场景,可能很容易就想到使用 join api ,直接将两个流 join 起来。
实际上,这样个需求,使用 join api 是不太适合的, join 是基于窗口的,要在窗口内有关联的数据,才能进行后续的计算。 这个需要中,规则流的某些规则在整个程序的执行周期里,可能只会有一次。
对应这样的需要,Flink 提供了 “Broadcast State” 来解决,具体请查看官网:The Broadcast State Pattern https://ci.apache.org/projects/flink/flink-docs-release-1.11/zh/dev/stream/state/broadcast_state.html (现在有中文翻译了)
调用DateStream 的 broadcast 方法,将一个流解释成广播流,再调用非广播流(keyed 或者 non-keyed)的 connect() 关联, 将 BroadcastStream 当做参数传入。 这个方法的返回参数是 BroadcastConnectedStream,具有类型方法 process(),传入一个特殊的 CoProcessFunction 来书写我们的关联逻辑。
一般来说使用广播流的时候,在每个并发中都会保留广播的全部数据(可能没办法区分那些是需要的,那些不需要),这样就会导致广播状态越来越大,如果广播状态更新比较频率的,就不太适用了。
注: 广播状态使用的是 Operator State,运行时保存在内存中。
所以就进入了今天的重点是 connect 在非广播流中的使用。
官网关于 connect 算子,只在 算子概览(https://ci.apache.org/projects/flink/flink-docs-release-1.11/zh/dev/stream/operators/) 中简单的描述了 connect 算子
DataStream,DataStream → ConnectedStreams"Connects" two data streams retaining their types. Connect allowing forshared state between the two streams.
DataStream someStream = //...
DataStream otherStream = //...
ConnectedStreams connectedStreams = someStream.connect(otherStream);
看过上面广播状态