Flink 数据倾斜怎么排查和治理?
面试怎么回答
Flink 数据倾斜要从同一算子各 Subtask 的吞吐、Busy、Backpressure、状态大小和延迟差异确认。keyBy 后单个热点 Key 只能进入一个实例,提高并行度无法拆开它;可结合聚合适合加盐做局部加全局两阶段,不可拆的顺序语义则要调整业务粒度或单独隔离。还要排除 Kafka 分区不均和外部 I/O 热点,并验证改造后的状态兼容与结果一致性。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
一个 Flink 作业整体 CPU 只有 35%,却持续反压。点开 Subtask 后发现:15 个实例很空闲,只有 1 个实例 CPU、Busy Time 和 State 全部打满。
实时任务的倾斜不是“平均资源不够”,而是数据或状态没有均匀落到并行实例。
Flink 倾斜要从各 Subtask 的吞吐、Busy、Backpressure 和 State 差异确认,再区分热点 Key、分区策略、数据源分区和外部 I/O,按语义选择拆分方案。
先用 Subtask 差异确认倾斜
不要只看作业总 CPU。对比同一算子各 Subtask 的 records in/out、busy time、backpressure、状态大小、Checkpoint 对齐和处理延迟。一个实例持续显著高于中位数,才有倾斜证据。
热点 Key 是最常见原因
keyBy 保证相同 Key 进入同一个逻辑分区,这是状态一致性的基础,也意味着超级用户、默认值或空 Key 会集中到一个实例。提高并行度不能拆开同一个 Key,只会增加更多空闲实例。
也可能是上游分区不均
Kafka 分区数量和热点、rebalance 后的分配、rescale 或自定义 partitioner,都可能让 source 或下游分布不均。若倾斜从 source 就开始,先治理 Kafka Key 和分区;若 keyBy 后才出现,则看业务 Key。

拆热点要先确认计算语义
可结合的聚合可以做两阶段:给热点 Key 加随机盐做局部聚合,再去盐做全局聚合。普通 Key 走原路径,热点 Key 单独分流。若是严格按用户顺序处理,就不能随意拆 Key,需要改业务粒度或单独扩容隔离。
外部 I/O 慢也会伪装成倾斜
某个分区命中了大量维表查询、下游限流或异常数据重试,也会表现为单 Subtask 忙。要结合异步请求耗时、失败率和外部系统日志判断,避免把 I/O 热点误判为纯数据量问题。
治理后验证状态和一致性
改 Key 或并行度会影响状态分布和升级路径。上线前要评估 Savepoint 兼容、Exactly-Once、顺序和结果去重;上线后比较最大与中位 Subtask 的吞吐、延迟、状态大小和 Checkpoint 时间。
参考资料
- Apache Flink:Windows - Keyed vs Non-Keyed Windows:https://nightlies.apache.org/flink/flink-docs-stable/docs/dev/datastream/operators/windows/#keyed-vs-non-keyed-windows