flink源码分析之Broadcast State

注意事项

broadcast state主要适用于规则匹配这样的场景中,规则的数据量较小且规则的变更频率较少.

而且broadcast state目前的statebackend不支持rockdb这样的存储,而只有本地内存的存储方式,所以要注意内存的适用.

Broadcast State实现的一般步骤

1 首先要有两个DataStream ,一个数据流,一个规则流
DataStream<Action> actions = env.addSource(new KafkaConsumer<>());
DataStream<Pattern> patterns = env.addSource(new KafkaConsumer<>());
2 对数据流进行转化,且对规则转化为广播流
KeyedStream<Action,Long> actionsByUser = actions.keyBy((KeySelector<Action,Long>) action -> action.userId);
MapStateDescriptor<Void,Pattern> bcStateDescriptor = new MapStateDescriptor<>(
"patterns",Types.VOID,Types.POJO(Pattern.class))
BroadcastStream<Pattern> bcPatterns = pattern.broadcast(bcStateDescriptor)
3 对数据流和广播流进行connect操作,并自定义process处理逻辑
DataStream<Tuple2<Long,Pattern>> matches = actionsByUser.connect(bcPatterns)
.process(new PatternEvaluator());
4 PatternEvaluator是具体的处理逻辑,包括三个方法
open:对状态的初始化
processElement:对数据流的处理
processBroadcastElement:对规则流的更新操作

PatternEvaluator具体处理逻辑解析

public static class PatternEvaluator extends ProcessBroadcastFunction<Long,Action,Pattern,Tuple2<Long,Pattern>>{
    //前一刻状态
    ValueState<String> preActionState;
    //广播状态描述符
    MapStateDescriptor<Void,Pattern> patternDesc;

    public void open(Configuration conf){
        //初始化keyedState并注册
        preActionState = getRuntionContext().getState(
            new ValueStateDescriptor("lastAction",Types.STRING)
        )
        patternDesc = new MapStateDescriptor<>("pattern",Types.VOID,Types.POJO(
        Pattern.class));
    }
}
public void processElement(
             Action action,
             ReadOnlyContext ctx,
             Collector<Tuple2<Long,Pattern>> out)throws Exception{
    //从当前的broadcast state中获得pattern
    Pattern pattern = ctx.getBroadcastState(this.patternDesc)
                         .get(null);
    //获得之前的行为
    String preAction = preActionState.value();
    if(patter != null && preAction != null){
        //将pattern和前一行为以及当前行为对比,是否符合规则
        if(pattern.firstAction.equals(preAction) &&
           pattern.secondActon.equals(action.action)){
            out.collect(new Tuple2<>(ctx.getCurrentKey(),pattern));
        }
    }
    //不论匹配与否都要更新当前的action
    preActionState.update(action.action);
    
}
//可变的上下文环境
public void processBroadcastElement(
                            Pattern pattern,
                            Context ctx,
                            Collector<Tuple2<Long,Pattern>> out){
    BroadcastState<Void,Pattern> bcState = ctx.getBroadcastState(patternDesc);
    bcState.put(null,pattern);

}

 

代码段 小部件
[Dàimǎ duàn xiǎo bùjiàn]
Code segment widget
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值