1. Flink 基础入门:从流处理说起
大家好,我是这次课程的主讲。在正式开始之前,我想先聊聊我自己的经历。
几年前,我接手了一个实时数仓项目。业务方要求数据延迟不能超过 10 秒,数据量却每天上亿条。我当时第一反应是:用 Spark Streaming 吧,毕竟生态成熟。结果呢?踩了不少坑。后来换成了 Flink,问题才真正解决。从那以后,我对 Flink 就有了特别的感情。
所以这一章,我想带你从头认识 Flink。它到底是什么?为什么能成为实时计算的事实标准?
1.1 Flink 是什么?
Flink 是一个分布式流处理引擎。说白了,它就是用来处理「源源不断产生的数据」的。
你想想看,传统的数据处理方式,是把数据存到数据库里,然后再用 SQL 去查。这叫批处理。但现实世界的数据是流式的——用户点击、交易记录、传感器信号,它们无时无刻不在产生。
Flink 的核心思想就是:数据一来,立刻处理。它不等待,不攒批,每条数据到达时都能触发计算。
核心概念速览:
- 无界流:数据源源不断,没有终点。比如实时日志、交易流水。
- 有界流:数据有明确的开始和结束。比如一天的历史日志文件。
- 有状态计算:Flink 能记住中间结果。比如统计过去 5 分钟的点击量,它不需要每次都从头算。
- 精确一次语义:数据不会丢,也不会重复算。这在金融场景下至关重要。
我记得刚接触 Flink 时,最让我震撼的就是它的「事件时间」机制。传统流处理框架大多依赖数据到达的时间(处理时间),但 Flink 可以基于事件实际发生的时间来计算。这意味着即使数据延迟到达,结果依然是准确的。嗯,这一点在实时 ETL 里特别有用。
1.2 Flink 的发展历史与核心优势
Flink 的故事要从 2010 年说起。当时它还是柏林工业大学的一个研究项目,叫 Stratosphere。2014 年,它成为 Apache 顶级项目,正式更名为 Flink。
为什么它能后来居上?我总结了几点:
| 优势 | 说明 | 我的体会 |
|---|---|---|
| 真正的流处理 | 每条数据到达时立即处理,不是微批 | 延迟可以做到毫秒级,Spark Streaming 的微批至少几百毫秒 |
| 强大的状态管理 | 内置 RocksDB、内存等多种状态后端 | 我在做用户行为分析时,状态大小达到 TB 级,Flink 依然稳定 |
| 精确一次语义 | 端到端的一致性保证 | 曾经因为数据重复导致报表出错,换成 Flink 后问题消失 |
| 事件时间支持 | 基于事件发生时间而非到达时间 | 处理乱序数据时,这个特性简直是救命稻草 |
| 丰富的 API | DataStream、Table/SQL、CEP 等 | 从简单过滤到复杂事件匹配,一套框架搞定 |
个人建议:如果你刚开始学 Flink,不要急着看底层原理。先跑通一个简单的 WordCount 流式版本,感受一下「数据一来就处理」的感觉。我当初就是这么入门的。
1.3 Flink 应用场景
Flink 能做的事情很多。我挑三个最典型的场景来讲。
1.3.1 实时 ETL
这是 Flink 最广泛的应用。数据从 Kafka 进来,经过清洗、转换、过滤,再写回 Kafka 或数据库。
举个例子:
// 一个简单的实时 ETL 示例
DataStream<String> source = env.addSource(new FlinkKafkaConsumer<>("input-topic", ...));
DataStream<UserEvent> cleaned = source
.map(line -> parseAndClean(line)) // 数据清洗
.filter(event -> event.isValid()) // 过滤无效数据
.map(event -> enrichWithDimension(event)); // 维度补全
cleaned.addSink(new FlinkKafkaProducer<>("output-topic", ...));
我在项目中遇到过一个问题:原始日志里有些字段是空的,下游系统一遇到空值就报错。后来我在 Flink 里加了一个简单的 filter,把空值行直接丢弃,问题就解决了。你看,实时 ETL 就是这么灵活。
1.3.2 实时数仓
传统数仓是 T+1 的,今天只能看昨天的数据。实时数仓不一样,数据产生后几秒钟就能查询。
Flink 在实时数仓中的角色通常是:
- 从 Kafka 读取 ODS 层数据
- 进行实时清洗和关联,生成 DWD 层
- 做轻量聚合,写入 DWS 层
- 最终写入 ClickHouse、Doris 等 OLAP 引擎
我记得有一次,业务方要求大屏上的 GMV 数据延迟不超过 5 秒。我们用 Flink 做实时聚合,数据从下单到展示,全程不到 3 秒。业务方当场就竖了大拇指。
1.3.3 事件驱动应用
这类应用不是简单的 ETL,而是根据数据内容触发业务逻辑。比如:
- 风控系统:检测到异常交易,立即冻结账户
- 实时推荐:用户浏览商品后,实时更新推荐列表
- IoT 监控:设备温度超标,立刻报警
Flink 的 CEP(复杂事件处理)库就是为这类场景设计的。你可以定义规则,比如「5 分钟内连续失败 3 次」,Flink 会自动匹配模式并触发动作。
避坑指南:我曾经在一个事件驱动项目里,把状态设置得太大,导致 Checkpoint 超时。后来我改用 RocksDB 状态后端,并合理设置 TTL,问题才解决。记住:状态不是越大越好,要定期清理过期数据。
1.4 Flink vs Spark Streaming 对比
这个问题几乎每次技术选型都会被问到。我直接说结论:没有银弹,看场景。
但如果你问我个人偏好,实时性要求高的场景,我选 Flink;批处理为主、偶尔做流处理的,Spark 更合适。
| 对比维度 | Flink | Spark Streaming |
|---|---|---|
| 处理模型 | 真正的流处理(逐条处理) | 微批处理(攒一批再处理) |
| 延迟 | 毫秒级 | 秒级(取决于批次间隔) |
| 状态管理 | 原生支持,功能强大 | 需要借助外部存储 |
| 事件时间 | 原生支持,处理乱序数据能力强 | 支持,但不如 Flink 灵活 |
| SQL 支持 | Table API & SQL,持续演进 | Structured Streaming,生态成熟 |
| 批处理能力 | 可以,但非强项 | 强项,Spark 核心能力 |
| 学习曲线 | 中等,概念较多 | 较低,如果熟悉 Spark 的话 |
你可能会问:那到底怎么选?我一般这样判断:
- 如果延迟要求 < 1 秒,或者需要处理乱序数据,选 Flink
- 如果团队已经深度使用 Spark,且延迟要求不高,选 Spark Streaming
- 如果既要批处理又要流处理,且希望一套代码搞定,可以考虑 Flink 的批流一体
一个小技巧:做技术选型时,不要只看技术指标。团队的技术栈、人员能力、运维成本,这些都要考虑进去。我曾经见过一个团队,明明 Flink 更适合,但因为没人会 Java,最后选了 Spark。结果呢?开发效率低,线上问题不断。所以,选型要务实。
本章知识体系总览
下面这张图,是我为你梳理的本章核心知识结构。你可以把它当作一张地图,随时回来查阅。
这张图把本章的核心内容串起来了。你可以看到,Flink 的定位、历史、场景和对比,其实是一个完整的逻辑链条。理解了这些,后面的实战内容就会轻松很多。