每次无法通过processElement函数进行BroadCastState

时间:2019-04-23 13:30:30

标签: apache-flink flink-streaming

我正在尝试第一次使用BroadCastState。我按照文档中的一个小示例对其进行了测试。我使用KeyedBroadcastProcessFunction并从processBroadcastElement函数更新Map状态,但是当我尝试从processElement函数获取状态以收集它时。有时它输出需求,有时则什么都不输出。是什么原因造成的?

这是使用的代码。

DataStream<Tuple4<String,String,Integer,Integer>> similarityTuples = inputStream
                .keyBy(1)
                .connect(usersBroadCasted)
                .process(new KeyedBroadcastProcessFunction<String, Tuple3<String,String,Float>, String, Tuple4<String,String,Integer,Integer>>() {

                    MapStateDescriptor<Integer, String> usersBroadcastState =
                            new MapStateDescriptor<>(
                                    //"patterns", BasicTypeInfo.VOID_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO);
                                    "patterns", BasicTypeInfo.INT_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO);

                    ListState<String> usersLikedItem;

                    @Override
                    public void processElement(Tuple3<String, String, Float> input, ReadOnlyContext readOnlyContext, Collector<Tuple4<String, String, Integer, Integer>> out) throws Exception {

                        for(String user : usersLikedItem.get()){
                          out.collect(Tuple4.of(user,input.f0,1,0));
                        }
                        usersLikedItem.add(input.f0);

                        for (Map.Entry<Integer, String> entry : readOnlyContext.getBroadcastState(usersBroadcastState).immutableEntries()){                **out.collect(Tuple4.of(input.f0,entry.getValue(),0,10000));**
                        }
                    }

                    @Override
                    public void processBroadcastElement(String s, Context context, Collector<Tuple4<String, String, Integer, Integer>> collector) throws Exception {

                        context.getBroadcastState(usersBroadcastState).put(0,s);

                    }

我希望得到这个输出,有时它会输出我期望的结果,而无需更改代码中的任何内容(必填)

(10,40,0,10000)
(10,20,1,0)
(20,40,0,10000)
(10,30,1,0)
(20,30,1,0)
(30,40,0,10000)
(40,40,0,10000)

但有时会输出以下内容

(10,20,1,0)
(10,30,1,0)
(20,30,1,0)

1 个答案:

答案 0 :(得分:0)

不能保证广播状态元素和正常元素到达操作员的顺序总是以相同的顺序发生。这取决于生成元素的上游运算符。这就是为什么有时看到完整的输出,有时只看到没有广播状态元素(所有正常元素到达广播状态元素之前)的原因。

如果要保证您已经看到所有元素到某个点,则需要等待水印(并生成它们),并且仅当您看到相应的水印表示不再有水印时才进行处理。时间戳低于水印的元素将到达。