Apache Flink 实时流计算应用
Apache Flink 实时流计算应用
什么是 Apache Flink
Apache Flink 是一个分布式流处理框架,专为有状态的计算而设计,能够以高吞吐、低延迟的方式处理无界(流式)和有界(批量)数据集。
数据源 → [Source] → [Transformation] → [Sink] → 目标存储
Kafka Map/Filter/Join MySQL
Socket Window/Aggregate ES
File Dashboard
核心架构
集群组件
┌─────────────────────────────────────────┐
│ Client │
│ (提交 Job,生成 JobGraph) │
└──────────────────┬──────────────────────┘
│
┌──────────────────▼──────────────────────┐
│ JobManager (Master) │
│ ┌─────────────┐ ┌──────────────────┐ │
│ │ Dispatcher │ │ ResourceManager │ │
│ └─────────────┘ └──────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ JobMaster (调度执行图) │ │
│ └─────────────────────────────────┘ │
└──────────────────┬──────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│TaskMgr 1│ │TaskMgr 2│ │TaskMgr 3│
│ [Slot] │ │ [Slot] │ │ [Slot] │
│ [Slot] │ │ [Slot] │ │ [Slot] │
└─────────┘ └─────────┘ └─────────┘
核心技术原理
1. 数据流模型
Flink 将计算抽象为 DAG(有向无环图):
JobGraph(逻辑图)
↓ 优化/并行化
ExecutionGraph(物理执行图)
↓ 部署
Task 在各 TaskManager 上并行运行
并行度示例:
Source (并行度=2) Map (并行度=4) Sink (并行度=2)
[S1] ──────────→ [M1] [M2]
──→ [K1]
[S2] ──────────→ [M3] [M4]
──→ [K2]
2. 时间语义
Flink 提供三种时间概念:
$$ \text{Event Time} \leq \text{Ingestion Time} \leq \text{Processing Time} $$
Watermark 机制(解决乱序问题):
事件流(乱序): t=1, t=5, t=3, t=8, t=2, t=10 ...
↑
Watermark = max(EventTime) - 允许延迟
Watermark 推进 → 触发窗口计算
$$ Watermark(t) = \max(\text{observed event time}) - \Delta_{delay} $$
3. 窗口机制(Window)
滚动窗口 (Tumbling): [──5min──][──5min──][──5min──]
滑动窗口 (Sliding): [──10min──]
[──10min──]
[──10min──] (每5min滑动)
会话窗口 (Session): [活动─Gap─][活动──Gap─][活动]
全局窗口 (Global): [──────────────────────────────]
代码示例:
// 滚动时间窗口:每5分钟统计一次
stream
.keyBy(event -> event.userId)
.window(TumblingEventTimeWindows.of(Time.minutes(5)))
.aggregate(new CountAggregator())
.print();
// 滑动窗口:窗口10分钟,每2分钟计算一次
stream
.keyBy(event -> event.category)
.window(SlidingEventTimeWindows.of(Time.minutes(10), Time.minutes(2)))
.sum("amount");
4. 状态管理(State)
Flink 的核心优势之一是有状态计算:
无状态计算: Input → [f(x)] → Output
有状态计算: Input → [f(x, state)] → Output
↕
State Backend
(本地 or 远程存储)
State 类型:
State Backend 选择:
HashMapStateBackend → 内存(适合开发测试)
EmbeddedRocksDB → 本地磁盘(适合大状态生产环境)
+ Checkpoint → 远端持久化(HDFS / S3)
5. Checkpoint & 容错机制
基于 Chandy-Lamport 分布式快照算法:
正常数据流:
Source ──[d1][d2][d3]──────────────────→ Operator → Sink
插入 Barrier:
Source ──[d1][d2][barrier_n][d3][d4]──→ Operator → Sink
↓
触发状态快照保存
State → HDFS/S3
↓
Checkpoint 完成确认
故障恢复流程:
故障发生
→ 回滚到最近 Checkpoint
→ 重置 Source 到对应 offset(如 Kafka offset)
→ 从保存状态继续计算
→ 实现 Exactly-Once 语义
三种处理语义:
$$ \text{At Most Once} \subset \text{At Least Once} \subset \text{Exactly Once} $$
6. 反压机制(Backpressure)
上游生产速度 > 下游消费速度 → 反压触发
Producer ──[████████]──→ Buffer满 → 阻塞上游
↓
自动调速(无需外部干预)
Flink 利用 TCP 流控 + 网络缓冲区 实现天然反压,无需额外配置。
典型应用场景
┌─────────────────────────────────────────────────────┐
│ 实时数据管道 Kafka → Flink → ES/数据仓库 │
├─────────────────────────────────────────────────────┤
│ 实时风控 用户行为流 → 规则引擎 → 预警 │
├─────────────────────────────────────────────────────┤
│ 实时报表 订单流 → 聚合统计 → Dashboard │
├─────────────────────────────────────────────────────┤
│ CEP 复杂事件 行为序列检测(欺诈、异常) │
├─────────────────────────────────────────────────────┤
│ 机器学习推理 特征实时计算 → 在线预测 │
└─────────────────────────────────────────────────────┘
Flink vs Spark Streaming 对比
快速入门示例
// 经典 WordCount 流式版本
StreamExecutionEnvironment env =
StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> text = env.socketTextStream("localhost", 9999);
DataStream<Tuple2<String, Integer>> wordCount = text
.flatMap((String line, Collector<Tuple2<String, Integer>> out) -> {
for (String word : line.split(" ")) {
out.collect(Tuple2.of(word, 1));
}
})
.returns(Types.TUPLE(Types.STRING, Types.INT))
.keyBy(tuple -> tuple.f0)
.sum(1);
wordCount.print();
env.execute("Streaming WordCount");
总结
Flink 核心价值体系
高吞吐 ──────────────── 低延迟
\ /
\ /
\ /
──── 精确语义 ────
|
有状态计算
|
故障自动恢复
Flink 通过 流批一体 + 精确状态管理 + Checkpoint 容错 构建了当前最完善的实时计算体系,是大数据实时处理领域的事实标准之一。