Apache flink Flink MapState在TTL清理期间清理映射键的整个值

Apache flink Flink MapState在TTL清理期间清理映射键的整个值,apache-flink,flink-streaming,Apache Flink,Flink Streaming,我要求在flink map状态下为每个键保留最后25秒的值,但TTL会在达到25秒后立即删除整个值。请看我的代码,在代码列表中,每秒钟保存每个传感器id的传入数据,为了减少内存存储,我只需在列表中保留25秒的数据,有什么方法可以实现吗?TTL清除整个列表 public class ContinousDataProcessor extends KeyedProcessFunction<String,SensorData,Tuple2<String,Integer>&g

我要求在flink map状态下为每个键保留最后25秒的值,但TTL会在达到25秒后立即删除整个值。请看我的代码,在代码列表中,每秒钟保存每个传感器id的传入数据,为了减少内存存储,我只需在列表中保留25秒的数据,有什么方法可以实现吗?TTL清除整个列表

public class ContinousDataProcessor
    extends   KeyedProcessFunction<String,SensorData,Tuple2<String,Integer>> {

private transient MapState<String, List<SensorData>> SensorValueMapState;
private static final long serialVersionUID = 1L;

@Override
public void open(Configuration config) {
    MapStateDescriptor<String, List<SensorData>> varibaleTagValueMapDescriptor = new MapStateDescriptor(
            "variableTagValueMapState", String.class, SensorData.class);
    StateTtlConfig ttlConfig = StateTtlConfig.newBuilder(Time.seconds(25))
            .setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
            .setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired).build();

    varibaleTagValueMapDescriptor.enableTimeToLive(ttlConfig);
    SensorValueMapState= getRuntimeContext().getMapState(varibaleTagValueMapDescriptor);

}

@Override
public void processElement(SensorData inputData, Context arg1, Collector arg2) throws Exception {


    if (SensorValueMapState.contains(inputData.sensorId)) {
        SensorValueMapState.get(inputData.sensorId).add(inputData);
    } else {
        List<SensorData> sensorDataList = new ArrayList<>();
        sensorDataList.add(inputData);
        SensorValueMapState.put(inputData.sensorId, sensorDataList);
    }

            for (SensorData str : SensorValueMapState.get(inputData.sensorId)) {

        System.out.println(str.eventTime);          
    }}
公共类ContinousDataProcessor
扩展KeyedProcessFunction{
私有瞬态映射状态传感器值映射状态;
私有静态最终长serialVersionUID=1L;
@凌驾
公共无效打开(配置){
MapStateDescriptor VariableTagValueMapDescriptor=新的MapStateDescriptor(
“variableTagValueMapState”,String.class,SensorData.class);
StateTtlConfig ttlConfig=StateTtlConfig.newBuilder(时间.秒(25))
.setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
.setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired).build();
VariableTagValueMapDescriptor.enableTimeToLive(ttlConfig);
SensorValueMapState=getRuntimeContext().getMapState(VariableTagValueMapDescriptor);
}
@凌驾
public void processElement(SensorData inputData、上下文arg1、收集器arg2)引发异常{
if(SensorValueMapState.contains(inputData.sensorId)){
SensorValueMapState.get(inputData.sensorId).add(inputData);
}否则{
List sensorDataList=新建ArrayList();
sensorDataList.add(输入数据);
SensorValueMapState.put(inputData.sensorId、sensorDataList);
}
for(SensorData str:SensorValueMapState.get(inputData.sensorId)){
System.out.println(str.eventTime);
}}

据我所知,您希望列表中的每个元素都应用TTL。 在您的案例中,列表是映射状态中的一个值。映射状态对映射状态中的用户值的结构没有深入了解。这是状态后端中数据布局的限制。因此,在当前实现中,无法对每个元素应用TTL

TTL应用于值状态下的每个用户值、列表状态下的每个用户元素以及映射状态下的每个用户键/值对

根据应用程序的要求,您可以使用复合键尝试列表状态:

key of KeyedProcessFunction = current key of your KeyedProcessFunction + your current map state key

这不允许通过KeyedProcessFunction的当前键轻松获取所有列表,尽管您现在可以这样做。

感谢阿扎格雷宾,在我的情况下,KeyedProcessFunction的键和mapstate的键是相同的。您能建议此复合键如何解决此问题吗?如果键相同(sensorId)然后不确定为什么需要映射状态,因为映射状态对于每个sensorId()。如果改为使用ListState,则其中的每个元素将以其自身的25秒超时而不是一次终止整个列表。但ListState不如java list灵活,例如,您无法通过索引轻松更改/访问每个元素。ListState将始终隐式地为KeyedPrProcessFunction的每个键创建,因为您始终在处理输入数据,并通过processElement中的某个键访问ListState。您好,感谢您提供的详细信息。看起来我的代码片段有点混淆了您的想法。想象一下这样一种情况,我们从不同的传感器获取来自不同公司分支的连续数据,在这种情况下,KeyedPrProcessFunction的键是BRNACHID,我必须为每个分支创建一个MapState,该MapState包含传感器特定的数据,时间通常为10秒。我的MapState看起来像,我希望场景现在清楚了。在这种情况下,我如何使用TTL从每个传感器ID的列表值中删除值。很抱歉打扰您。好的,所以KeyedProcessFunction和MapState中的键不同。然后我可以继续建议我在主要答案中已经写过的内容。复合键应该是(BRNACHID,SENSORID)在KeyedProcessFunction中,MapState将被ListState替换。如果继续使用MapState,TTL将应用于整个列表>,因为它是Flink的blackbox java对象,每个元素没有任何内部TTL。TTL将应用于每个Flink状态条目。