2. Flink 基础回顾:架构、DataStream API、时间语义与 Watermark

在深入 Flink CEP 实时风控与 PSI 监控之前,必须夯实 Flink 核心基础。本章将系统回顾 Flink 的运行时架构、DataStream API 的核心抽象、两种时间语义的区别以及 Watermark 机制的工作原理。这些概念是理解后续复杂事件处理与状态管理的前提。

2.1 Flink 运行时架构

Flink 采用经典的 主从(Master-Worker)架构,由 JobManager 和 TaskManager 组成,配合 Client 提交作业,形成完整的分布式执行链路。

架构要点: JobManager 负责协调、调度与容错;TaskManager 负责执行具体的算子任务;Client 负责编译与提交作业图。
Flink 运行时架构 Flink 运行时架构 Client JobManager 调度 · 协调 · 容错 · Checkpoint TaskManager 1 Slot 1 | Slot 2 | Slot 3 TaskManager 2 Slot 1 | Slot 2 | Slot 3 TaskManager 3 Slot 1 | Slot 2 | Slot 3 TaskManager 的 Slot 数量决定并行度上限,JobManager 通过 RPC 管理所有 TaskManager

2.2 DataStream API 核心概念

DataStream API 是 Flink 流处理的核心编程模型,围绕 Source、Transformation、Sink 三大阶段构建数据处理管道。

概念 说明 风控场景示例
DataStream 无界数据流的核心抽象,支持事件序列的转换操作 用户登录事件流、交易事件流
Source 数据输入源,如 Kafka、Socket、文件 从 Kafka Topic 读取风控事件
Transformation 算子转换:map、filter、keyBy、window、process 按用户 ID keyBy,统计窗口内失败次数
Sink 数据输出目标,如 Kafka、MySQL、HDFS 将告警结果写入 Kafka 或数据库
KeyedStream 按 key 分区的流,用于状态隔离与窗口计算 按设备指纹或用户 ID 分区
实战提示: 在风控场景中,keyBy 是核心操作。按用户 ID、设备 ID 或 IP 进行分区,可以隔离不同实体的状态,避免跨实体干扰。

2.3 时间语义:Event Time vs Processing Time

Flink 提供两种时间语义,选择哪种直接决定计算结果的准确性与延迟。

  • Processing Time(处理时间):算子所在机器的本地时钟时间。延迟低、吞吐高,但结果受机器时钟和事件到达顺序影响,不可复现。
  • Event Time(事件时间):事件实际发生的时间,通常嵌入在事件数据中。结果可复现、准确,但需要配合 Watermark 处理乱序。
对比维度 Processing Time Event Time
准确性 低(依赖到达顺序) 高(基于事件实际发生时间)
延迟 低(无需等待) 较高(需容忍乱序)
可复现性 不可复现 可复现(相同输入得到相同输出)
风控适用性 低(不适合精确统计) 高(PSI 监控、窗口聚合必须用)
注意: 在 PSI 稳定性监控中,必须使用 Event Time。因为 PSI 计算依赖特征分布的时间窗口对齐,使用 Processing Time 会导致窗口边界漂移,计算结果不可信。

2.4 Watermark 机制

Watermark 是 Flink 解决 乱序事件 的核心机制。它本质上是一个时间戳标记,表示“在此时间戳之前的事件已经全部到达”。当 Watermark 超过窗口结束时间时,触发窗口计算。

Watermark 与乱序事件处理 Watermark 与乱序事件处理 t1 t2 t3 t4 t5 E1 E2 E3 E4 E2' Watermark = t3 窗口 [t1, t3) Watermark = t3 表示 t3 之前的事件已全部到达,此时触发窗口 [t1, t3) 的计算 乱序事件 E2'(实际时间 t2)在 Watermark 到达前被正确纳入窗口 若 E2' 在 Watermark 之后到达,则被标记为迟到事件,进入侧输出流

Watermark 生成策略

Flink 提供两种内置 Watermark 生成器,也可自定义 WatermarkStrategy。

// 示例:使用 BoundedOutOfOrdernessWatermark 生成 Watermark
DataStream<Event> stream = env
    .fromSource(kafkaSource, 
        WatermarkStrategy.<Event>forBoundedOutOfOrderness(Duration.ofSeconds(5))
            .withTimestampAssigner((event, timestamp) -> event.getEventTime()),
        "Kafka Source");
生成策略 说明 适用场景
forMonotonousTimestamps 假设事件时间严格递增,无乱序 日志时间戳有序的场景
forBoundedOutOfOrderness 允许最大乱序时间,如 5 秒 风控事件流,允许一定延迟
自定义 WatermarkStrategy 实现 onEvent 和 onPeriodicEmit 方法 需要根据业务特征动态调整
PSI 监控中的 Watermark 配置: 在实时 PSI 计算中,建议设置 forBoundedOutOfOrderness(Duration.ofSeconds(10)),以容忍网络抖动和事件乱序,同时保证窗口计算在合理延迟内触发。

2.5 小结