订阅更新

时间语义与Watermark:实时计算最核心的概念

Flink 实时计算 20 天 · 第 2 讲 基础 约 4 分钟读完

Event Time · Processing Time · Watermark · 乱序处理

本文目录
  1. 📋 面试题
  2. 三种时间语义
  3. Watermark到底是什么?
  4. Watermark传播机制
  5. 乱序时间设多大?
  6. 面试加分提示
  7. 📌 总结

📋 面试题

Flink的三种时间语义有什么区别?Watermark是什么?解决什么问题?

💡 先想30秒,再往下看答案


三种时间语义

时间类型 定义 场景
Event Time 事件实际发生的时间(数据自带的时间戳) 生产环境首选,结果确定性
Processing Time 数据被Flink处理时的机器时间 延迟最低,但结果不确定
Ingestion Time 数据进入Flink的时间 几乎不用

面试一句话:生产环境用Event Time,因为结果可重现。Processing Time依赖机器时钟,任务重启后结果可能不同。

我们广告归因场景必须用Event Time。用户3点点击广告,5点下单,归因逻辑要基于事件发生时间来匹配。如果用Processing Time,任务重启或数据延迟到达时,归因结果就乱了。

Watermark到底是什么?

一句话:Watermark是一个时间戳,告诉Flink「这个时间之前的数据应该都到齐了」。

数据流(带时间戳):
[10:01] [10:03] [10:02] [10:05] [10:04] ...
                                    ↑
            数据是乱序到达的,10:02比10:03晚到

Watermark(10:03) 的含义:
"我认为10:03之前的数据都到齐了,可以触发10:00-10:05窗口的计算了"

核心理解:Watermark = 当前最大Event Time - 允许的乱序时间

// 允许5秒乱序
WatermarkStrategy
    .<Event>forBoundedOutOfOrderness(Duration.ofSeconds(5))
    .withTimestampAssigner((event, ts) -> event.getTimestamp());

如果当前收到的最大Event Time是10:10,Watermark就是10:05。意味着Flink认为10:05之前的数据都到了。

Watermark传播机制

多个并行度时,Watermark怎么传递?

Source(并行度2):
  Source[0] Watermark: 10:05
  Source[1] Watermark: 10:03

下游算子取 min(10:05, 10:03) = 10:03
→ 下游的Watermark = 10:03

取所有上游的最小值。这意味着一个Source慢了,整个下游的Watermark都会被拖慢。

我遇到过一次:Kafka某个Partition长时间没有新数据,导致对应Source的Watermark不推进,整条链路的窗口都不触发。解决方案是设置Idle Source超时:

WatermarkStrategy
    .forBoundedOutOfOrderness(Duration.ofSeconds(5))
    .withIdleness(Duration.ofMinutes(1)); // 1分钟没数据就标记为Idle

乱序时间设多大?

场景 建议乱序容忍 原因
内部系统日志 1-5秒 网络延迟小
APP埋点 5-30秒 网络波动、后台上报
跨境/出海数据 30秒-2分钟 跨国网络延迟大

我们出海业务设的30秒。刚开始设5秒,发现海外用户的数据经常延迟10-20秒到达,大量数据被判定为迟到丢弃了。调到30秒后迟到率从15%降到2%以下。

面试加分提示

💡 三层递进回答:

「第一,生产用Event Time,结果可重现。第二,Watermark等于当前最大Event Time减去乱序容忍时间。第三,多并行度时取所有上游Watermark的最小值。

我们出海业务设了30秒乱序容忍,还遇到过Kafka Partition无数据导致Watermark不推进的问题,用withIdleness解决的。」

📌 总结

记忆点 内容
生产首选 Event Time,结果确定可重现
Watermark 最大Event Time - 乱序容忍时间
传播规则 下游取所有上游Watermark的最小值
Idle Source 无数据的Partition会拖慢Watermark,用withIdleness
乱序时间 根据数据源特性设,出海场景需要更大

▶ 下一篇预告:DAY 3 窗口机制


Wood聊大数据 | 9年大数据老兵,聊技术、聊职场、聊成长


小红书正文

Watermark是Flink面试最高频的概念题,也是最容易讲不清楚的。

一句话:Watermark是一个时间戳,告诉Flink「这个时间之前的数据都到齐了」。公式:Watermark = 当前最大Event Time - 允许的乱序时间。

关键细节:多并行度时取所有上游的最小值。所以一个Source慢了,整条链路的窗口都不触发。

我踩过的坑:Kafka某个Partition长时间没新数据,Watermark不推进,所有窗口都卡住了。用withIdleness(1分钟)解决。

乱序时间设多大?内部日志1-5秒,APP埋点5-30秒,出海数据30秒-2分钟。我们一开始设5秒,海外数据迟到率15%,调到30秒后降到2%。

刷题进度保存在当前浏览器