Flink IntervalJoin 依赖 ** 事件时间(Event Time)** 实现基于数据自身时间字段的关联,核心是通过TimestampAssigner将数据中的时间字段提取为事件时间戳,并配合WatermarkStrategy生成水位线(处理乱序数据)。以下是详细的步骤、代码示例和关键注意事项,教你如何指定数据里的时间字段。
一、核心原理:事件时间 + 水位线
IntervalJoin 是Keyed Stream的操作,且仅支持事件时间(不支持处理时间)。要绑定数据中的时间字段,需完成两个关键步骤:
- 提取事件时间戳:将数据中的时间字段(如
order_time、pay_time,格式可以是时间戳毫秒数、日期字符串等)转换为 Flink 识别的事件时间戳(毫秒级 Long 类型)。 - 生成水位线(Watermark):定义水位线策略,处理乱序数据,确保 IntervalJoin 能正确关联时间范围内的数据。
二、步骤拆解:如何指定数据中的时间字段
步骤 1:定义数据实体(包含时间字段)
首先定义数据流的实体类,包含需要作为时间字段的属性(如orderTs、payTs)。
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
// 订单数据:订单ID、用户ID、下单时间(毫秒时间戳)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
private Integer orderId;
private Integer userId;
private Long orderTs; // 数据中的时间字段(毫秒级时间戳)
}
// 支付数据:订单ID、支付金额、支付时间(毫秒时间戳)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Pay {
private Integer orderId;
private Double amount;
private Long payTs; // 数据中的时间字段(毫秒级时间戳)
}
步骤 2:为数据流分配时间戳和水位线
使用assignTimestampsAndWatermarks方法,结合WatermarkStrategy,将数据中的时间字段提取为事件时间戳,并生成水位线。
场景 1:时间字段是毫秒级时间戳(Long 类型)
这是最常见的场景,直接提取即可。
import org.apache.flink.api.common.eventtime.*;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
public class IntervalJoinWithTimeField {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.ge

最低0.47元/天 解锁文章
913

被折叠的 条评论
为什么被折叠?



