在flink中,大多数state只作用于各自的算子,算子间不能共用state,BroadcastProcessFunction和KeyedBroadcastProcessFunction则作用于全局算子,进行数据共享,类似于spark中的广播变量,但只能在广播端进行数据的读写,非广播端只有读操作。如果DataStream需要使用广播流时,通过connect函数进行融合。
Broadcast State
Broadcast State是一个mapstate,所以Descriptor要创建为MapStateDescriptor
val ruleStateDescriptor = new MapStateDescriptor[JsonObject](
"RulesBroadcastState",
BasicTypeInfo.STRING_TYPE_INFO,
TypeInformation.of(new TypeHint[JsonObject]() {}))
val ruleBroadcastStream = dataStream.broadcast(ruleStateDescriptor)
BroadcastStream可以通过调用connect()非广播流(以keyBroadcastStream为参数)来将流(keyDataStream或DataStream)与进行连接。这将返回一个BroadcastConnectedStream,我们可以在其中调用process()特殊类型的ProcessFunction。该函数将包含我们的处理逻辑。函数的具体类型取决于非广播流的类型:
- 如果使用key,则该函数为
KeyedBroadcastProcessFunction。 - 如果使用no-key,则该函数为
BroadcastProcessFunction。
BroadcastProcessFunction和KeyedBroadcastProcessFunction
两种process function都含有processElement和processBroadcastElement方法,分别用来处理非广播元素和广播元素。不同点在于ctx方面,非广播方法有ReadOnlyContext(对广播元素只读,原因是在Flink中没有跨任务通信,保证Broadcast State在所有task中元素相同,保证state一致性),广播方法有Context。
public abstract class BroadcastProcessFunction<IN1, IN2, OUT> extends BaseBroadcastProcessFunction {
public abstract void processElement(IN1 value, ReadOnlyContext ctx, Collector<OUT> out) throws Exception;
public abstract void processBroadcastElement(IN2 value, Context ctx, Collector<OUT> out) throws Exception;
}
public abstract class KeyedBroadcastProcessFunction<KS, IN1, IN2, OUT> {
public abstract void processElement(IN1 value, ReadOnlyContext ctx, Collector<OUT> out) throws Exception;
public abstract void processBroadcastElement(IN2 value, Context ctx, Collector<OUT> out) throws Exception;
public void onTimer(long timestamp, OnTimerContext ctx, Collector<OUT> out) throws Exception;
}
两个ctx有共同属性:
- 允许访问广播状态:
ctx.getBroadcastState(MapStateDescriptor<K, V> stateDescriptor) - 允许查询元素的时间戳:
ctx.timestamp() - 得到当前的水印:
ctx.currentWatermark() - 获得当前处理时间:
ctx.currentProcessingTime() - 将元素进行侧输出:
ctx.output(OutputTag<X> outputTag, X value)
3297

被折叠的 条评论
为什么被折叠?



