flink BoundedOutOfOrdernessTimestampExtractor

博客介绍首次注册时生成当前最大时间戳的规则,即 currentMaxTimestamp 等于 lastEmittedWatermark 加上时间间隔 maxOutOfOrderness。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BoundedOutOfOrdernessTimestampExtractor 实现了
AssignerWithPeriodicWatermarks (注册周期生成Watermarks)

源码如下

第一次注册会生成当前最大时间戳currentMaxTimestamp =lastEmittedWatermark + 时间间隔(maxOutOfOrderness)
在这里插入图片描述

public abstract class BoundedOutOfOrdernessTimestampExtractor<T> implements AssignerWithPeriodicWatermarks<T> {
      
	private static final long serialVersionUID = 1L;

	/** The current maximum timestamp seen so far. */
	//定义当前最大时间戳
	private long currentMaxTimestamp;

	/** The timestamp of the last emitted watermark. */
	//最后提交的时间戳
	private long lastEmittedWatermark = Long.MIN_VALUE;

	/**
	 * The (fixed) interval between the maximum seen timestamp seen in the records
	 * and that of the watermark to be emitted.
	 */
	private final long maxOutOfOrderness;

	public BoundedOutOfOrdernessTimestampExtractor(Time maxOutOfOrderness) {
		if (maxOutOfOrderness.toMilliseconds() < 0) {
			throw new RuntimeException("Tried to set the maximum allowed " +
				"lateness to " + maxOutOfOrderness + ". This parameter cannot be negative.");
		}
		this.maxOutOfOrderness = maxOutOfOrderness.toMilliseconds();
		this.currentMaxTimestamp = Long.MIN_VALUE + this.maxOutOfOrderness;
	}

	public long getMaxOutOfOrdernessInMillis() {
		return maxOutOfOrderness;
	}

	/**
	 * Extracts the timestamp from the given element.
	 *
	 * @param element The element that the timestamp is extracted from.
	 * @return The new timestamp.
	 */
	public abstract long extractTimestamp(T element);

	@Override
	public final Watermark getCurrentWatermark() {
		// this guarantees that the watermark never goes backwards.
		//这个句代码保证了生成的水印是单调递增的
		//当前最大的时间戳减去延时时间和上次最后提交的水印时间比较
		//保留最大的时间(减去延时时间)作为水印
		long potentialWM = currentMaxTimestamp - maxOutOfOrderness;
		if (potentialWM >= lastEmittedWatermark) {
			lastEmittedWatermark = potentialWM;
		}
		return new Watermark(lastEmittedWatermark);
	}

//提取数据中时间作为timestamp
//如果timestamp 大于最大的currentMaxTimestamp 就把currentMaxTimestamp 置为 timestamp
//返回当前提取到的timestamp
	@Override
	public final long extractTimestamp(T element, long previousElementTimestamp) {
		long timestamp = extractTimestamp(element);
		if (timestamp > currentMaxTimestamp) {
			currentMaxTimestamp = timestamp;
		}
		return timestamp;
	}
}

### Flink 中的时间处理特性 Flink 提供了强大的时间处理机制,允许开发者精确控制事件时间和处理时间。为了实现复杂的时间窗口计算和其他基于时间的操作,Flink 暴露了 `TimestampAssigner` 接口,使得可以从事件数据中自定义提取时间戳的方法[^1]。 #### 自定义时间戳分配器 对于需要特定方式解析时间戳的应用场景,可以通过实现 `TimestampAssigner` 来指定如何从记录中获取时间信息: ```java public class CustomTimestampAssigner implements TimestampAssigner<MyEvent> { @Override public long extractTimestamp(MyEvent element, long recordTimestamp) { // 假设 MyEvent 类有一个 getTime() 方法返回 Unix 时间戳 return element.getTime(); } } ``` 此方法确保即使在乱序到达的情况下也能正确识别每条消息的实际发生时刻。 #### 处理水印 (Watermark) 除了时间戳外,Flink 还引入了 Watermarks 的概念用于表示事件序列中的进度标记。这有助于解决延迟到来的数据问题,并支持更复杂的业务逻辑需求。例如,在某些情况下可能希望设置最大容忍度内的迟到数据处理策略: ```java DataStream<Event> streamWithWatermarks = inputStream .assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<Event>(Time.seconds(5)) { @Override public long extractTimestamp(Event event) { return event.getCreationTime(); // 获取创建时间作为时间戳 } }); ``` 上述代码片段展示了如何配置一个最多接受五秒内无序的消息流,并自动丢弃超出该范围的旧数据项。 然而值得注意的是,尽管 Flink 支持多种灵活的时间管理功能,但它并不直接提供所谓“时间旅行”的能力——即回溯到过去某个状态执行查询的能力。要达到类似效果通常依赖于外部存储系统保存历史版本的状态快照,或是利用 Apache Flink State Processor API 对 checkpointed state 执行离线分析作业[^2].
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值