2. Flink 基础回顾:架构、核心概念与开发环境搭建
在进入实时特征服务开发之前,有必要系统回顾 Flink 的核心基础。本章将围绕 Flink 的运行时架构、核心编程抽象(DataStream、算子、时间语义)以及开发环境搭建三个维度展开,为后续的因子计算实战打下坚实的技术根基。
2.1 Flink 运行时架构
Flink 采用经典的 主从(Master-Worker)架构,由 JobManager 和 TaskManager 两个核心组件构成,配合 Dispatcher 和 ResourceManager 实现作业的提交、调度与容错。
2.2 核心概念:DataStream、算子与时间语义
2.2.1 DataStream 与数据流模型
DataStream 是 Flink 流处理的核心抽象,代表一个持续不断、可能有界或无界的数据流。所有算子操作都围绕 DataStream 展开,包括转换(Transformation)、分区(Partitioning)、窗口(Window)和状态(State)管理。
| 概念 | 说明 | 典型场景 |
|---|---|---|
| DataStream<T> | 未分区的流,元素类型为 T | 从 Kafka Source 读取原始事件 |
| KeyedStream | 按 Key 分区的流,支持状态与窗口 | 按用户 ID 分组计算累计特征 |
| WindowedStream | 在 KeyedStream 上定义窗口后的流 | 每 5 分钟统计一次滑动平均 |
| ConnectedStreams | 两条流的连接,可共享状态 | 实时特征与标签流的关联 |
2.2.2 常用算子分类
Flink 算子按功能可分为 基本转换算子、KeyBy 与分区算子、窗口算子 和 状态算子 四大类。以下列出特征服务开发中最常用的算子:
- map / flatMap / filter:单元素转换、一对多展开、条件过滤。
- keyBy:按指定 Key 对数据流进行逻辑分区,后续才能使用状态和窗口。
- reduce / aggregate:增量聚合,适合滑动平均、累加器等特征。
- process:最灵活的算子,可访问时间、状态和输出,适合复杂特征逻辑。
- assignTimestampsAndWatermarks:分配时间戳并生成 Watermark,驱动事件时间窗口。
keyBy + process 是最常用的组合。process 算子可以同时管理多个状态变量,并精确控制输出时机,非常适合因子计算中的多步聚合逻辑。
2.2.3 时间语义与 Watermark
Flink 支持三种时间语义,在特征服务中 事件时间(Event Time) 是最常用的选择,因为它能正确处理乱序数据和回填场景。
| 时间语义 | 定义 | 特征服务适用性 |
|---|---|---|
| 事件时间(Event Time) | 事件实际发生的时间,由业务字段携带 | ✅ 推荐,能处理乱序和延迟数据 |
| 摄入时间(Ingestion Time) | 事件进入 Flink 的时间 | ⚠️ 仅用于对时间精度要求不高的场景 |
| 处理时间(Processing Time) | 算子所在机器的当前系统时间 | ❌ 不推荐,结果不可复现 |
Watermark 是事件时间窗口的“进度信号”,表示“当前时间之前的数据已经全部到达”。Watermark 的生成策略直接影响窗口触发时机和特征计算的准确性。
2.3 Flink 开发环境搭建
2.3.1 环境依赖清单
在开始编码之前,需要确保以下基础环境就绪:
- JDK 8 或 11(推荐 JDK 11,Flink 1.14+ 官方支持)
- Apache Maven 3.6+ 或 SBT 1.5+(Scala 项目)
- IDE:IntelliJ IDEA(推荐)或 Eclipse
- Git:用于版本管理和项目模板克隆
2.3.2 Maven 项目模板(推荐)
使用 Flink 官方提供的 Maven Archetype 快速生成项目骨架:
mvn archetype:generate \
-DarchetypeGroupId=org.apache.flink \
-DarchetypeArtifactId=flink-quickstart-java \
-DarchetypeVersion=1.17.1 \
-DgroupId=com.featurefactory \
-DartifactId=realtime-feature-service \
-Dversion=1.0.0 \
-Dpackage=com.featurefactory \
-DinteractiveMode=false
生成后的项目结构如下:
realtime-feature-service/
├── pom.xml
└── src/
└── main/
├── java/com/featurefactory/
│ ├── StreamingJob.java # 主入口
│ └── FeatureCalculator.java # 特征计算逻辑
└── resources/
└── log4j.properties
2.3.3 SBT 项目模板(Scala 用户)
对于 Scala 项目,推荐使用 sbt-flink-template 或手动配置 build.sbt:
// build.sbt
name := "realtime-feature-service"
version := "1.0.0"
scalaVersion := "2.12.17"
libraryDependencies ++= Seq(
"org.apache.flink" %% "flink-streaming-scala" % "1.17.1",
"org.apache.flink" %% "flink-clients" % "1.17.1",
"org.apache.flink" % "flink-connector-kafka" % "1.17.1"
)
scalaVersion 改为 2.13.10,并将依赖中的 %% 替换为 _2.13 显式指定。
2.3.4 本地运行验证
在 IDE 中直接运行 StreamingJob.main(),Flink 会自动启动一个嵌入式 MiniCluster,无需额外部署。验证输出日志包含以下内容即表示环境搭建成功:
INFO org.apache.flink.runtime.minicluster.MiniCluster - Starting Flink Mini Cluster
INFO org.apache.flink.runtime.executiongraph.ExecutionGraph - Job "Flink Streaming Job" switched to state RUNNING
INFO com.featurefactory.StreamingJob - Feature calculation pipeline started.