赞
踩
Watermark(水印)概念
在 Apache Flink 流处理框架中,Watermark 是一个关键的时间概念,用于处理事件时间窗口(event-time processing)中的乱序事件问题。事件时间是指事件本身携带的时间戳,而非数据到达或被处理的时间(即处理时间)。由于网络延迟等因素,事件可能会乱序到达,为了确保在某个时间窗口内完成所有相关的事件处理,Flink 引入了 Watermark 机制。
水印原理
水印是一个特殊的时间戳,代表了某个时间点之前的数据理论上应该都已经到达了系统,即“最多允许的延迟”。例如,如果当前水印值为 t
,那么意味着所有时间戳小于等于 t
的事件都应该已经到达了流处理系统。一旦水印时间戳超过了窗口结束时间,窗口就可以被认为是完整的,并触发窗口计算。
水印的作用
核心示例代码(基于 Flink 1.16 版本的 Java API)
Apache Flink 1.16 版本对水印生成器进行了重构,现在推荐使用 WatermarkStrategy
类配合 TimestampAssigner
和 TimestampExtractor
接口来实现。以下是基于 Flink 1.16+ 版本的 Watermark 生成器示例代码:
import org.apache.flink.api.common.eventtime.*; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.windowing.time.Time; // 假设有一个事件类 MyEvent,其中包含一个 long 类型的 eventTimestamp 字段 public class MyEvent { public long eventTimestamp; // 其他属性和构造方法... } public class CustomWatermarkStrategy extends WatermarkStrategy<MyEvent> { @Override public WatermarkGenerator<MyEvent> createWatermarkGenerator(WatermarkGeneratorSupplier.Context context) { return new BoundedOutOfOrdernessWatermarkGenerator<>(Time.seconds(10)); // 允许10秒乱序 } @Override public TimestampAssigner<MyEvent> createTimestampAssigner(TimestampAssignerSupplier.Context context) { return (event, timestamp) -> event.eventTimestamp; // 从事件中提取时间戳 } } public class CustomWatermarkGeneratorExample { public static void main(String[] args) throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 假设有一个 DataStreamSource<MyEvent> DataStreamSource<MyEvent> events = ...; // 创建并应用自定义水印策略 DataStream<MyEvent> withTimestampsAndWatermarks = events .assignTimestampsAndWatermarks(new CustomWatermarkStrategy()); // 定义窗口操作 withTimestampsAndWatermarks .keyBy(event -> event.getKey()) // 假设根据某个键进行分区 .window(TumblingEventTimeWindows.of(Time.seconds(30))) // 使用30秒滚动窗口 .reduce(new MyReduceFunction()); // 自定义窗口内事件的合并函数 env.execute("Watermark Example Job"); } } class MyReduceFunction implements ReduceFunction<MyEvent> { // 实现窗口内事件的合并逻辑 @Override public MyEvent reduce(MyEvent value1, MyEvent value2) { // ... return resultEvent; } }
在这个示例中,CustomWatermarkStrategy
继承自 WatermarkStrategy<MyEvent>
并分别实现了 createWatermarkGenerator
和 createTimestampAssigner
方法。BoundedOutOfOrdernessWatermarkGenerator
是 Flink 内置的一个实用类,它可以根据指定的延迟时间自动产生水印。
createTimestampAssigner
方法指定了如何从 MyEvent
对象中获取事件时间戳,而 createWatermarkGenerator
方法则创建了一个基于允许最大乱序时间(这里是10秒)的水印生成器。当事件时间戳的时间超过当前水印时间戳时,窗口就会被认为完整并触发计算。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。