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

相关推荐
张紫娃3 分钟前
Spring @Scope, @Lazy, @DependsOn, @Required, @Lookup
java·后端·spring
简诚4 分钟前
java实现RabbitMQ消息发送和接收功能(包含测试)
java·rabbitmq·java-rabbitmq
結城1 小时前
Spring Security如何拿到登录用户的信息
java·spring·mybatis
顽强卖力2 小时前
数据分析六部曲?
大数据·数据挖掘·数据分析
GalaxyPokemon2 小时前
LeetCode - 2. 两数相加
java·前端·javascript·算法·leetcode·职场和发展
dualven_in_csdn5 小时前
搞了两天的win7批处理脚本问题
java·linux·前端
C++chaofan7 小时前
74. 搜索二维矩阵
java·算法·leetcode·矩阵
AWS官方合作商7 小时前
亚马逊云科技 Amazon Pinpoint 解决方案:构建智能全渠道互动平台,重塑用户增长体验
大数据·科技·aws
诺浅8 小时前
AWS S3 SDK FOR JAVA 基本使用及如何兼容七牛云
java·spring boot·aws
迢迢星万里灬8 小时前
Java求职者面试:微服务技术与源码原理深度解析
java·spring cloud·微服务·dubbo·netty·分布式系统