Flink中的时间语义和TTL

时间语义

事件时间(Event Time)

事件时间是数据生成的时间,是数据流中每个元素或者每个事件自带的时间属性,一般是事件发生的时间,在实际项目中作为前端的一个属性嵌入。在理想情况下,数据应当按照事件时间顺序到达集群节点,但是由于从产生一条数据到数据抵达集群有过多的中间步骤,一个较早发生的事件可能较晚到达,使用事件时间意味着会产生数据乱序。

处理时间(Processing Time)

处理时间执行处理操作的机器的系统时间,使用处理时间不需要依赖水位线,也无需缓存,实现也十分简单,是延迟最小的一种时间语义。

注入时间(Ingestion Time)

注入时间是数据进入 Source 算子的时间,任何一个算子的处理速度快慢可能影响到下游算子的处理时间,但是注入时间仅依赖于数据进入 Source 算子的时间,因此不会受制于不同算子的计算时间。

水位线和事件时间

水位线的物理意义有两点:

  1. 水位线本质是一个基于数据生成的、单调递增的时间戳;
  2. 水位线 W(t)表示当前数据流中的所有 t 时刻前的数据都已经到了。

水位线的传播

在实际计算过程中,Flink 的算子一般分布在多个并行的分区(或者称为实例)上,Flink 需要将 Watermark 在并行环境下向前传播。如下图所示,由于上游各分区的处理速度不同,到达当前算子的 Watermark 也会有先后快慢之分,每个算子子任务会维护来自上游不同分区的 Watermark 信息,这是一个列表,列表内对应上游算子各分区的 Watermark 时间戳等信息。每当一个上游传递过来一个水位线,实例会判断该水位线是否大于列表中记录的数值,如果大于则更新水位线。接着实例会遍历整个水位线列表找出最小值作为实例的事件时间,最后,实例会将更新的 Event Time 作为 Watermark 发送给下游所有算子子任务。

时间事件的提取和水位线的生成

周期性的生成水位线,默认周期是 200 毫秒 。可以使用 ExecutionConfig.setAutoWatermarkInterval() 方法进行设置。

我们也可以使用 assignTimestampsAndWatermarks() 来分配时间戳和水位线。该方法主要依赖于 WatermarkStrategy 接口,通过 WatermarkStrategy 我们可以为每个元素抽取时间戳并生成 Watermark。基本的使用方法如下:

复制代码
DataStream.assignTimestampsAndWatermarks(WatermarkStrategy  
        .<Event>forBoundedOutOfOrderness(Duration.ZERO)  
        .withTimestampAssigner((SerializableTimestampAssigner<Event>)  
                (element, recordTimestamp) -> element.timeStamp))

forGenerator () 方法用来生成 Watermark,本质是返回了一个 WatermarkGenerator 有俩种实现机制**,** BoundedOutOfOrdernessWatermarks(数据存在乱序的情况)AscendingTimestampsWatermark(数据有序)

withTimestampAssigner () 方法用来为数据流的每个元素设置时间戳

TTL

java 复制代码
public void open(Configuration parameters) throws Exception {
        // 创建MapState描述符
        MapStateDescriptor<String, Long> descriptor = new MapStateDescriptor<>("myMapState", String.class, Long.class);
        StateTtlConfig ttlConfig = StateTtlConfig
                // 状态有效时间
                .newBuilder(Time.seconds(10))
                //设置状态更新类型
                .setUpdateType(StateTtlConfig.UpdateType.OnReadAndWrite)
                // 已过期但还未被清理掉的状态如何处理
                .setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
                // 过期对象的清理策略
                .cleanupFullSnapshot()
                .build();
        descriptor.enableTimeToLive(ttlConfig);
        mapState = getRuntimeContext().getMapState(descriptor);
    }

配置分析

设置状态更新类型

复制代码
setUpdateType(StateTtlConfig.UpdateType.OnReadAndWrite):

在读和写的时候更新过期时间

复制代码
setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite):

只在创建和写的时候更新过期时间 (默认)

已过期但还未被清理掉的状态如何处理

复制代码
setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)

不返回过期值

复制代码
setStateVisibility(StateTtlConfig.StateVisibility.ReturnExpiredIfNotCleanedUp)

可以返回过期值

过期转态的清理策略

⭐ lazy 删除策略:就是在访问 State 的时候根据时间戳判断是否过期,如果过期则主动删除 State 数据

⭐ full snapshot cleanup 删除策略:从状态恢复(checkpoint、savepoint)的时候采取做过期删除,但是不支持 rocksdb 增量 ck

⭐ incremental cleanup 删除策略:访问 state 的时候,主动去遍历一些 state 数据判断是否过期,如果过期则主动删除 State 数据

⭐ rocksdb compaction cleanup 删除策略:rockdb 做 compaction 的时候遍历进行删除。仅仅支持 rocksdb

相关推荐
lang2015092816 分钟前
Java JSR 250核心注解全解析
java·开发语言
czhc114007566326 分钟前
协议 25
java·开发语言·算法
逆光的July27 分钟前
如何解决超卖问题
java
落花流水 丶33 分钟前
Java 集合框架完全指南
java
绝缘体138 分钟前
如何使用外卖霸王餐api接口?
大数据·搜索引擎·微信·pygame
lang201509281 小时前
Java WebSocket API:JSR-356详解
java·python·websocket
jiang_changsheng1 小时前
环境管理工具全景图与深度对比
java·c语言·开发语言·c++·python·r语言
计算机学姐1 小时前
基于SpringBoot的民宿预定管理系统【三角色+个性化推荐算法+数据可视化统计】
java·vue.js·spring boot·mysql·信息可视化·intellij-idea·推荐算法
yaoxin5211231 小时前
314. Java Stream API - 使用 Collectors.partitioningBy() 分区元素
java·windows
noBt1 小时前
Windows IDEA 卡顿严重
java·ide·intellij-idea