结论先给你
不是每个 TaskManager 一份,是每个Subtask(并行子任务)都存一份完整、相同的 BroadcastState;同一个 TaskManager 上如果跑多个 Subtask,每个 Subtask 各自独立存一份,不是共享同一份。
1. 层级搞清楚
- Job → 多个 TaskManager(节点)
- 每个 TM 上跑多个 Subtask(并行子任务)
- BroadcastState 粒度:按 Subtask 隔离
2. 真实存储分布
假设:
- 作业并行度 = 4
- 2 个 TaskManager,每个 TM 跑 2 个 Subtask
分布:
- TM1:Subtask1 有一份完整广播状态、Subtask2 也各自独立一份完整副本
- TM2:Subtask3 一份、Subtask4 一份
👉4 个 Subtask,就有 4 份一模一样的 BroadcastState 副本不是按 TM 只存一份,是每个子任务都完整存一份。
3. 为什么不按 TaskManager 只存一份?
- Flink 状态最小单元是Subtask,不是 TM
- 故障容错、重启、扩容缩容都是按 Subtask 做快照、恢复
- 如果 TM 内多个 Subtask 共享一份广播状态,重启 / 迁移时会互相影响,架构更复杂
4. 带来的特点
- 优点:每个子任务本地直接读广播规则,无跨节点查询、性能高
- 缺点:并行度越高,副本数越多、占用内存放大;规则很大时内存开销明显
5. 面试一句话背诵
BroadcastState 不是每个 TaskManager 存一份,而是每个并行 Subtask 都会单独存储一份完整相同的广播数据;同一个 TaskManager 上多个子任务各自持有独立副本,不共享,并行度越高副本数量越多,内存开销随之增大。
补充:和 KeyedState 对比记忆
- KeyedState:按 Key 拆分,分散在各个 Subtask
- BroadcastState:全量复制,每个 Subtask 都完整存一份
如何使用BroadcastState?
除了BroadcastState,还有哪些常见的KeyedState?
如何保证BroadcastState的一致性?