Flink
一条一条算的流处理引擎,也能顺带把批算了
Flink 把“数据流”当第一公民:数据一条条流过算子,窗口到点就计算。它用 Checkpoint 定期给状态拍快照,故障时从最近一次快照恢复,做到 Exactly-Once。批处理只是“有界的流”,所以一套代码能跑实时也能跑离线。
它解决什么问题
用 Spark Streaming 微批做实时,延迟被卡在秒级;而且状态(比如“用户连续登录失败 5 次”)要自己存 Redis,跨窗口、故障恢复全靠业务代码兜。
真实场景:典型场景:风控系统从 Kafka 读支付事件,按用户维度维护 10 分钟窗口的失败次数,超过阈值立刻推告警,要求延迟 1 秒内、不重不漏。
核心概念
每个概念一句话 + 一个类比。点击卡片看更详细的解释。
DataStream
Flink 里最核心的抽象,一条条事件组成的流,可以无限长
类比:传送带上的零件,一个接一个过来
看概念详情Watermark
告诉系统“时间 T 之前的数据基本到齐了”,用来处理乱序
类比:考试收卷,到点后默认没人再交,晚交的单独处理
看概念详情Window
把无限流切成有限片段再聚合,按时间或按条数切
类比:把一条长河按每 5 分钟舀一桶来化验
看概念详情State
算子在两条数据之间要记住的东西,比如“当前累计金额”
类比:记账本,每一笔都往上加
看概念详情Checkpoint
定期给状态拍快照存到 HDFS,挂了从这里恢复,做到不重不漏
类比:游戏存档,死了从最近的存档点重来
看概念详情数据流转动画
跟着步骤看一条数据从进入系统到被处理完的完整路径,可以暂停、重播和调速。
一条事件在 Flink 里的完整旅程
← 左右滑动查看完整流程图 →
Source 从 Kafka 拉取一条支付事件,带上事件时间戳和 offset。
提示:关键在 Watermark 和 Checkpoint:前者决定窗口什么时候算,后者决定挂了之后从哪继续。 悬停图中的节点可以看概念解释。
优劣势
短句说清适合什么、不适合什么,选型时先看这一栏。
- 真正的流处理,延迟毫秒到秒级,不是微批
- 状态管理内建,跨窗口累计、去重不用自己接 Redis
- Checkpoint + 两阶段提交,端到端 Exactly-Once
- 事件时间 + Watermark 能处理乱序数据
- 流批一体,同一套 API 跑实时和离线
- 概念多,Watermark / 状态 / 时间语义新手容易绕晕
- 状态大了依赖 RocksDB,调优和运维门槛高
- 作业一挂全链路停,需要做好高可用和监控
- 小数据量场景属于杀鸡用牛刀,资源开销不小
常见使用场景
每个场景都配一句「为什么用它」。
实时风控与反欺诈
按用户维护滑动窗口内的失败次数、金额累计,超阈值实时拦截。
为什么用它:需要状态 + 低延迟 + 不重不漏,正好是 Flink 的主场。
实时大屏与指标
从 Kafka 读埋点,按分钟聚合 GMV、UV、转化率,写进 ClickHouse / Doris。
为什么用它:事件时间 + 窗口聚合,能扛住乱序和迟到数据。
实时数仓 ODS → DWD
把 binlog 和业务事件流式清洗、打宽、写入湖仓表。
为什么用它:流批一体,同一份 SQL 逻辑白天跑流、晚上跑批校验。
同类对比
和同赛道的组件并排看,差异一目了然。
一句话:离线与准实时选 Spark,真实时选 Flink。两者不是替代关系,很多公司是 Spark 跑批、Flink 跑流,共用一套 Kafka 和数仓。
常见问题
上手第一个月最容易卡住的地方。
Q1Watermark 到底解决什么问题?
网络延迟会让事件乱序到达。如果没有 Watermark,系统不知道“还有没有更早的数据没来”,窗口就只能一直等。Watermark 是一个时间断言:水位线之前的数据基本到齐了,窗口可以算了。设太激进会丢迟到数据,设太保守会拖长延迟。
Q2Exactly-Once 是怎么做到的?
三件事配合:Source 记录 offset 并纳入 checkpoint;State 随 checkpoint 一起快照;Sink 用两阶段提交(预提交 + 收到 checkpoint 完成通知后正式提交)。恢复时从最近完成的 checkpoint 重放,保证每条数据只影响结果一次。
Q3Flink 和 Spark Streaming 的区别?
Spark Streaming 是微批:把流切成小批,延迟至少几百毫秒到秒级;Flink 是原生流:一条条处理,延迟可以做到毫秒。加上 Flink 的状态和事件时间支持更完整,做实时业务一般选 Flink,做准实时报表 Spark 也够用。
Q4状态越来越大怎么办?
先确认是否真的需要保留全量状态:能加 TTL 的加 TTL(StateTtlConfig),能用增量聚合就不存明细。状态到几十 GB 时必须用 RocksDB 状态后端 + 增量 checkpoint,并把 state 放在 SSD 上;再大就要考虑按 key 分片或换架构。