初始化MapState

时间:2019-10-09 15:06:52

标签: java apache-flink flink-streaming

我实现了具有以下结构的Flink RichFunction

public class MyFunction extends KeyedBroadcastProcessFunction <String, InputType, BroadcastedStateType, OutputType> {

    private MapState<String, MyState> myState;              

    @Override
    public void open(Configuration conf)throws Exception{
        myState = getRuntimeContext().getMapState(new MapStateDescriptor<>("state", Types.STRING, Types.POJO(BroadcastedStateType.class)));
    }

    @Override
    public void processElement(InputType value, ReadOnlyContext ctx, Collector<OutputType> out) throws Exception {
        MyState state = myState.get(value.ID());

        // Do things
    }

    @Override
    public void processBroadcastElement(BroadcastedStateType value, Context ctx, Collector<OutputType> out) throws Exception {
        state.put(value.ID(), value.state());   // Update the mapState with value from broadcast
    }

    // retrieve all the state values and put them in the MapState
    private void initialState() throws Exception{
       Map<String, MyState> initialValues = ...;
       this.cameras.putAll(initialValues);
    }
}

mapState变量存储通过BroadcastedStream更新的多个状态。更新是通过processBroadcastElement()函数完成的。

在工作开始时,我想使用mapState函数来初始化initialState()

问题是我无法在open()函数中使用它(请参阅here为什么)

在这种情况下,初始化mapState的正确方法是什么? (并且在所有情况下都使用RichFunctions)

2 个答案:

答案 0 :(得分:1)

您要实现org.apache.flink.streaming.api.checkpoint.CheckpointedFunction

执行此操作时,将实现两种方法:

@Override
public void snapshotState(FunctionSnapshotContext context) throws Exception {

    // called when it's time to save state

    myState.clear();

        // Update myState with current application state 

}

@Override
public void initializeState(FunctionInitializationContext context) throws Exception {

    // called when things start up, possibly recovering from an error

    descriptor = new MapStateDescriptor<>("state", Types.STRING, Types.POJO(BroadcastedStateType.class));

    myState = context.getKeyedStateStore().getMapState(descriptor);

    if (context.isRestored()) {

        // restore application state from myState  

    }       

}

您可以使用initializeState()方法而不是open()初始化myState变量。

答案 1 :(得分:0)

我不相信您实际上可以在initializeState()中初始化广播状态。修改广播状态的唯一方法是通过在processBroadcastElement方法中获得的读/写上下文。

但是您可以做的是在initializeState中使用context.isRestored()来确定KeyedBroadcastProcessFunction是否是第一次被初始化,并设置一个临时局部变量来记录此信息。然后,第一次调用processBroadcastElement方法时,您可以使用此信息来决定在广播状态下存储什么。但是您必须在广播流上发送一些内容才能开始。