对于Flink 1.8.1,我试图将State TTL应用于BroadcastState(使用MapStateDescriptor),如下所示:
(Holder是一个包装私有int变量“ deger”的POJO)
...
StreamExecutionEnvironment envStream = StreamExecutionEnvironment.getExecutionEnvironment();
StateBackend stateBackend = new FsStateBackend("file://.....");
envStream.setStateBackend(stateBackend);
envStream.enableCheckpointing(1_000L, CheckpointingMode.EXACTLY_ONCE);
...
MapStateDescriptor<Integer, Client> clientMapStateDescriptor = new MapStateDescriptor<>(
"ClientBroadcastState",
BasicTypeInfo.INT_TYPE_INFO,
TypeInformation.of(new TypeHint<Client>() {})
);
StateTtlConfig ttlConfig = StateTtlConfig
.newBuilder(Time.seconds(3))
// .cleanupFullSnapshot()
// .cleanupInBackground()
.cleanupIncrementally(100, false)
.setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
.setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
.build();
clientMapStateDescriptor.enableTimeToLive(ttlConfig);
DataStream<Client> clientDataStream = envStream.fromCollection(clientList);
// clientDataStream.print("clientDataStream");
BroadcastStream<Client> clientBroadcastStream = clientDataStream
.broadcast(clientMapStateDescriptor);
List<Holder> holderList = new ArrayList<>(count);
for(int i = 0; i < count; i++) {
holderList.add(new Holder(i));
}
DataStream<Holder> integerHolderDataStream = envStream.fromCollection(holderList);
BroadcastConnectedStream<Holder, Client> connectedStreams = integerHolderDataStream
.keyBy("deger")
.connect(clientBroadcastStream);
SingleOutputStreamOperator<Row> operator = connectedStreams.process(new KeyedBroadcastProcessFunction<Integer, Holder, Client, Row>() {
@Override
public void processElement(Holder value, ReadOnlyContext ctx, Collector<Row> out) throws Exception {
for (Map.Entry<Integer, Client> entry : ctx.getBroadcastState(clientMapStateDescriptor).immutableEntries()) {
Client c = ctx.getBroadcastState(clientMapStateDescriptor).get(entry.getKey());
System.out.println(value.getDeger() + " - " + c);
}
Thread.sleep(1000L);
}
@Override
public void processBroadcastElement(Client value, Context ctx, Collector<Row> out) throws Exception {
ctx.getBroadcastState(clientMapStateDescriptor).put(value.getId(), value);
}
});
...
holderList有足够的实例来测试状态项是否被驱逐。
但是BroadcastState
中的条目不会过期。
我尝试过的事情:
FsStateBackend
)我可能做错了什么? BroadcastState是否支持StateTTL?
如果没有,您能否提供一个示例(如何使用MapStateDescriptor)将广播状态中的条目逐出?
答案 0 :(得分:0)
根据FLIP-25中的内容,StateTTL仅用于键控状态。
只能在BroadcastProcessFunction(或Keyed BroadcastProcessFunction)的processBroadcastElement方法中写入或清除存储在BroadcastState中的项目-这意味着您必须在处理接收另一个广播元素的过程中执行此操作。而且,您需要注意在所有并行实例中使用完全相同的逻辑,因为Flink期望每个实例在BroadcastState的内容上都是一致的,如果您在此处进行不确定性或特定于实例的操作,可能会导致奇怪的事情。
一种解决方案是广播流记录,接收者将其解释为使较早记录从广播状态过期的命令。