三个时间概念
事件时间(Event Time)是数据实际发生的时刻,通常取自记录里的时间戳字段;处理时间(Processing Time)是引擎处理到这条记录时的本地时钟;摄入时间(Ingestion Time)是数据进入引擎系统的时刻,介于两者之间。三者中只有事件时间与数据的业务含义绑定,处理时间只反映机器的忙碌程度。
为什么对外指标要用事件时间
用处理时间统计时,网络延迟、积压或重启都会改变结果:同一批数据重跑两次,得到的数字可能完全不同。事件时间把归属交给数据本身,窗口边界与业务日期一致,结果可复现、可核对,也能与批处理口径对齐。
三种时间对照
| 时间语义 | 来源 | 特点 |
|---|---|---|
| 事件时间 | 记录内的时间戳字段 | 可复现、与业务对齐,需要水位线配合 |
| 处理时间 | 引擎所在机器的本地时钟 | 实现最简单,但不可复现,受积压影响 |
| 摄入时间 | 记录进入引擎的时刻 | 介于两者之间,不依赖数据自带时间戳 |
基本信息
| 事件时间 | 数据自带的发生时间,从记录字段中提取 |
|---|---|
| 处理时间 | 引擎本地时钟,结果随运行环境变化 |
| 配套机制 | 事件时间需要水位线判断完整性 |
| 对齐要求 | 多源时间戳的时区与格式必须先统一 |
| 典型取舍 | 延迟敏感用处理时间,口径敏感用事件时间 |
典型使用场景
- 对外报表与看板:按事件时间统计,多个来源口径才能对齐
- 跨系统对账:事件时间让两侧按同一业务时刻切分数据
- 实时告警:可以先用处理时间快速出结果,同时用事件时间做准
- 补数与重跑:重放历史数据时事件时间保证结果与首次一致
- 延迟分析:比较事件时间与处理时间之差,量化链路延迟
Flink SQL 声明事件时间
Flink SQL 声明事件时间
-- 把业务时间字段声明为事件时间,并给出允许迟到的时间
CREATE TABLE orders (
order_id STRING,
amount DECIMAL(10,2),
ts TIMESTAMP(3), -- 事件时间字段
WATERMARK FOR ts AS ts - INTERVAL '5' SECOND -- 容忍 5 秒乱序
) WITH ('connector' = 'kafka', 'topic' = 'orders', 'format' = 'json');
-- 窗口按事件时间切分:结果与数据发生时刻绑定,重启重跑可复现
SELECT TUMBLE_START(ts, INTERVAL '1' MINUTE) AS w, SUM(amount)
FROM orders GROUP BY TUMBLE(ts, INTERVAL '1' MINUTE);排查两套数字对不上时,先确认双方用的是哪种时间语义。实时链路按处理时间出数、离线链路按事件时间出数,是口径差异的常见来源,而不是数据本身错了。
用处理时间做统计并对外发布,重跑同一批数据会得到不同结果;对账时无法解释差异,也无法验证哪一次是对的。