下面从 Flink 中 keyBy 的工作原理 和 实际生产场景 出发,详细说明在 keyBy 之前 和 keyBy 之后,如何分别进行优化处理,以解决常见的 数据倾斜、背压、性能瓶颈 等问题。
1. Flink keyBy 简介
在 Flink 的 DataStream API 中,keyBy 是对流进行哈希分区的操作:
- 相同 key 的数据会被路由到同一个并行子任务(subtask)里;
- 不同 key 会分散到不同的 subtask,以实现分布式处理。
典型场景:分组聚合(keyBy(...).timeWindow(...))、KeyedProcessFunction、KeyedState 等需要根据 key 进行状态或窗口管理的场景。
2. keyBy 之前和 keyBy 之后的区别
-
keyBy 之前
- 数据尚未做哈希分区;
- 所有数据可以在上游算子统一处理,或者按照上游并行度直接发送给下游;
- 没有“相同 key 必须到同一并行子任务”的强制性,故无键控状态(可能是 operator state 或无状态);
- 算子之间若能 chaining,可以减少一次网络边界。
-
keyBy 之后
- 数据已根据 key 做哈希分区;
- 相同 key 的数据会集中到同一个 subtask;
- 如果 key 分布不均,容易出现数据倾斜或背压;
- 可使用 keyed state、keyed window、KeyedProcessFunction 等场景;
- 产生一次网络 shuffle(哈希分区),对性能有一定开销。
3. 常见问题及痛点
-
数据倾斜
- 如果某些 key 出现频率远高于其他 key(“hot key”),在 keyBy 之后,会导致某个 subtask 处理量极大,形成负载不均,吞吐下降,甚至背压蔓延。
-
背压
- 当下游算子处理不过来时,上游会被迫限速,整体吞吐下降。keyBy 之后某 subtask 成为瓶颈的现象很常见。
-
性能开销
- keyBy 产生一次网络 shuffle,会涉及序列化、反序列化和网络传输;在大流量场景中是不可忽视的成本。

最低0.47元/天 解锁文章
2495

被折叠的 条评论
为什么被折叠?



