一、Flink概述与核心概念

各位同学好,我是你们这门课的老朋友。今天咱们正式开篇,聊聊Flink到底是什么,它从哪来,能干什么,以及它跟Spark Streaming到底谁更胜一筹。这部分内容我建议你认真看,因为后面的所有实战都建立在这些基础认知上。

1.1 Flink的发展历史

Flink的故事,得从2010年说起。那时候它还不叫Flink,而是柏林工业大学的一个研究项目,代号"Stratosphere"。说白了,就是几个教授带着博士生,想搞一套能处理大规模数据的系统。我当年刚接触大数据时,用的还是Hadoop MapReduce,那叫一个痛苦——写个WordCount都得几十行代码,跑个任务等半天。

到了2014年,Stratosphere项目孵化出了Flink,并捐给了Apache基金会。同年12月,Flink成为Apache顶级项目。为什么叫Flink?德语里是"敏捷、灵巧"的意思。嗯,这名字起得挺贴切,因为它确实快。

我记得2016年左右,Flink在国内开始火起来。那时候阿里、美团、字节跳动这些大厂都在偷偷用。为什么?因为实时计算的需求爆发了。双11大屏、实时风控、实时推荐,这些场景用Spark Streaming做,延迟太高,扛不住。

到了2019年,阿里巴巴将内部的Blink(基于Flink改造的版本)回馈给社区,Flink 1.9版本正式合并了Blink的大量特性。这算是一个里程碑——Flink从此有了真正能打的生产级SQL支持。我那时候正好在做一个实时数仓项目,从Spark切到Flink,体验确实好了不止一个档次。

核心时间线:

  • 2010年 — 柏林工业大学启动Stratosphere项目
  • 2014年 — Flink成为Apache孵化项目,同年成为顶级项目
  • 2016年 — Flink在国内开始大规模应用
  • 2019年 — Flink 1.9合并Blink特性,SQL能力大幅增强
  • 至今 — Flink已成为实时计算领域的事实标准

1.2 Flink的应用场景

Flink能干什么?我直接给你列几个我亲眼见过的真实场景。

第一个,实时ETL和数据管道。 说白了,就是把数据从源头(比如Kafka)实时清洗、转换,然后写入目标系统(比如HBase、Elasticsearch)。我做过一个项目,每天处理几十亿条用户行为日志,延迟控制在秒级。用Flink的DataStream API,写起来很顺手。

第二个,实时监控与告警。 比如电商平台的订单风控。用户下单后,系统需要在毫秒级判断这笔交易有没有风险。Flink的CEP(复杂事件处理)库就是干这个的。我曾经帮一家金融公司做过反欺诈系统,规则引擎跑在Flink上,效果不错。

第三个,实时数仓。 这是目前最火的方向。传统数仓是T+1,今天看昨天的数据。实时数仓要求分钟级甚至秒级出报表。Flink + Hive/Kafka + ClickHouse,这套组合拳现在很多大厂都在用。

第四个,实时推荐。 你刷抖音、逛淘宝,看到的内容推荐,背后大概率有Flink的身影。用户的行为数据实时流入,Flink实时计算用户画像,然后推送个性化内容。

场景 典型需求 Flink优势
实时ETL 低延迟、高吞吐 Exactly-Once语义,状态管理强大
实时监控告警 复杂事件匹配 CEP库,毫秒级响应
实时数仓 分钟级OLAP SQL支持完善,与Hive集成好
实时推荐 实时特征计算 低延迟,状态后端灵活

1.3 Flink与Spark Streaming的对比

这个问题,几乎每次技术选型都会被问到。我直接说结论:没有银弹,看场景。

先说说核心区别。Spark Streaming的本质是微批次(Micro-Batch)。它把数据流切成一小段一小段,每段当成一个批处理任务来跑。而Flink是真正的流处理(True Streaming),每条数据来一条处理一条。

你想想看,微批次有什么问题?延迟。就算你把批次间隔设到100毫秒,那也有100毫秒的固定延迟。而且批次之间切换有开销。Flink呢?理论上延迟可以做到毫秒级。我做过对比测试,同样场景下,Flink的端到端延迟比Spark Streaming低一个数量级。

但Spark Streaming也有它的优势。生态成熟,跟Spark SQL、MLlib、GraphX无缝集成。如果你团队里已经有Spark全家桶,那用Spark Streaming做实时,学习成本低很多。

我个人的建议是:

  • 如果对延迟要求高(秒级以内),选Flink
  • 如果对吞吐要求极高,且能接受秒级延迟,Spark Streaming也能用
  • 如果要做实时数仓,Flink SQL更香
  • 如果团队Spark经验丰富,可以先从Spark Streaming入手

避坑指南: 我曾经在一个项目里,用Spark Streaming做实时风控,结果因为微批次的特性,导致某些高频交易事件被切分到不同批次里,规则匹配出了问题。后来切到Flink,用事件时间+Watermark,问题迎刃而解。所以,事件时间语义是Flink的一大杀器,后面我会详细讲。

对比维度 Flink Spark Streaming
处理模型 真正的流处理 微批次处理
延迟 毫秒级 秒级(取决于批次间隔)
事件时间支持 原生支持,Watermark机制完善 支持,但实现较复杂
状态管理 丰富的状态后端(RocksDB等) 基于RDD的Checkpoint
SQL支持 Flink SQL,持续演进 Structured Streaming,较成熟
Exactly-Once 端到端支持 需要外部系统配合

1.4 Flink的核心架构

这部分是重点,我建议你多看几遍。Flink的架构,说白了就是主从架构,但细节上有很多巧妙之处。

先看一张图,这是我画的Flink运行时架构图:

Flink运行时架构图 JobManager 作业调度 + 检查点协调 TaskManager 集群 TaskManager 1 Slot 1 | Slot 2 TaskManager 2 Slot 1 | Slot 2 TaskManager 3 Slot 1 | Slot 2 数据源 (Kafka/Socket) 数据输出 (HBase/ES) 说明: JobManager 负责接收作业、调度任务、协调 Checkpoint。 TaskManager 是真正干活的,每个 Slot 代表一个计算资源单元。

好,图看完了,我来拆解一下。

JobManager 是Flink集群的"大脑"。它负责接收用户提交的作业,然后生成执行计划,分发给TaskManager。它还负责协调Checkpoint,这是Flink容错机制的核心。我遇到过一个问题:JobManager挂了怎么办?答案是Flink支持高可用部署,依赖ZooKeeper做选主,备用的JobManager会自动顶上。

TaskManager 是真正干活的"工人"。每个TaskManager有多个Slot,Slot就是计算资源的最小单位。一个Slot可以跑一个子任务(SubTask)。你想想看,这有点像线程池的概念——Slot数量决定了并行度。

Client 是用户提交作业的入口。它把作业编译成JobGraph,然后发给JobManager。Client可以跑在本地,也可以跑在集群的某个节点上。

注意: 很多初学者会把Slot和并行度搞混。Slot是TaskManager上的物理资源槽,而并行度是作业的逻辑并行度。一个TaskManager的Slot数决定了它能同时跑多少个子任务。但并行度可以大于Slot总数吗?可以,但多余的子任务会排队等待。我曾经在生产环境踩过这个坑——并行度设得太大,Slot不够,导致任务堆积,延迟飙升。所以,并行度不要超过集群总Slot数,除非你清楚自己在做什么。

最后说说Flink的分层架构。从下往上:

  • 运行时层 — 提供分布式计算、容错、状态管理等核心能力
  • API层 — DataStream API(流处理)和DataSet API(批处理,已逐渐被Table API取代)
  • 高级API层 — Table API 和 SQL,这是目前最推荐的方式
  • 库层 — CEP(复杂事件处理)、Gelly(图计算)、StateBackend等

我个人习惯是:能用SQL解决的问题,绝不用DataStream API。为什么?开发效率高,维护成本低。但有些场景,比如自定义状态管理、复杂窗口逻辑,还是得用DataStream API。后面我会专门讲什么时候该用哪种API。