Flink面试_002、operator state 和 keyed state 两者的区别?最大并行度和这两种 state 的关系?

博客探讨了Flink中operator state和keyed state的区别,特别是在任务恢复和并行度变化时的行为。operator state适用于所有算子,而keyed state用于keyed-stream后的算子,且存储粒度为单key。并行度变化时,operator state通过ListState、BroadcastState或UnionListState进行恢复,keyed state则依赖key-group的重新划分。最大并行度与key-group数量绑定,影响state恢复,因此在调整并行度时需谨慎。

举个例子,当用户停止任务、更新代码逻辑并且改变任务并发度时,两种 state 都是怎样进行恢复的

1. 区分 operator-state 和 keyed-state 的方式
 a. operator-state:
  1. 状态适用算子:所有算子都可以使用 operator-state,没有限制。
  2. 如果需要使用 operator-state,需要实现 CheckpointedFunction 或 ListCheckpointed 接口
  3. DataStream API 中,operator-state 提供了 ListState、BroadcastState、UnionListState 3 种用户接口
  4. 状态的存储粒度:以单算子单并行度粒度访问、更新状态
  5. 并行度变化时:
   a. ListState:均匀划分到算子的每个 sub-task 上
   b. BroadcastState:每个 sub-task 的广播状态都一样
   c. UnionListState:将原来所有元素合并,合并后的数据每个算子都有一份全量状态数据
 b. keyed-state:
  1. 状态适用算子:keyed-stream 后的算子使用。注意这里很多同学会犯一个错误,就是大家会认为 keyby 后面跟的所有算子都使用的是 keyed-state,但这是错误的 ,比如有 keyby.process.flatmap,其中 flatmap 中使用状态的话是 operator-state
  2. 从 context 接口获取具体的 keyed-state
  3. DataStream API 中,keyed-state 提供了 ValueState、MapState、ListState 等用户接口,其中最常用 ValueState、MapState
  4. 状态的存储粒度:以单 key 粒度访问、更新状态。举例,当我们使用 keyby.proc

✅ **是的,Flink 服务被 `killed` 后重新启动,State 可以恢复 —— 前提是你启用了「检查点(Checkpointing)」「状态后端(State Backend)」并配置了正确的状态存储路径(如 HDFS、S3 等)。** --- ## 🧾 回答:Flink 被 killed 后重启能否恢复 State? | 条件 | 是否能恢复 State | |------|------------------| | ✅ 开启 Checkpoint + 配置持久化存储(HDFS/S3) | ✅ 是,自动从最近的 Checkpoint 恢复 | | ❌ 未开启 Checkpoint | ❌ 否,状态丢失 | | ✅ 开启 Checkpoint,但存储路径不可访问 | ❌ 否,无法读取历史状态 | | ✅ 使用 Savepoint 手动触发备份 | ✅ 是,可指定从 Savepoint 恢复 | --- ## 🔁 Flink 容错机制核心:Checkpoint 与 Savepoint ### 1. ✅ Checkpoint(自动容错) - Flink 内部定期自动触发; - 将算子状态(Operator State)、键控状态(Keyed State)写入分布式文件系统(如 HDFS、S3); - 当 Job 失败或被 `kill -9` 杀掉后,**使用 `--from-checkpoint` 或默认行为即可恢复状态**。 #### 示例代码(开启 Checkpoint): ```java StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 启用 Checkpoint:每 5 秒一次 env.enableCheckpointing(5000, CheckpointingMode.EXACTLY_ONCE); // 设置 Checkpoint 存储位置(必须是分布式存储) env.getCheckpointConfig().setCheckpointStorage("hdfs://namenode:8020/flink/checkpoints"); // 其他配置 env.getCheckpointConfig().setMinPauseBetweenCheckpoints(2000); env.getCheckpointConfig().setCheckpointTimeout(60000); env.getCheckpointConfig().setMaxConcurrentCheckpoints(1); ``` > ✅ 当你重启作业时: ```bash ./bin/flink run -d -c com.example.StreamingJob ./app.jar ``` Flink 会自动尝试从最新的 Checkpoint 恢复(如果配置了 `ExternalizedCheckpointRetention`)。 --- ### 2. 💾 Savepoint(手动备份/升级/迁移) - 用户手动触发:`flink savepoint <jobId> hdfs://path` - 更适合用于版本升级、并行度调整等场景; - 比 Checkpoint 更稳定、可长期保留。 #### 触发 Savepoint: ```bash # 查看运行中的作业 ID ./bin/flink list # 触发保存点 ./bin/flink savepoint <job-id> hdfs://namenode:8020/flink/savepoints ``` #### 从 Savepoint 启动: ```bash ./bin/flink run -s hdfs://namenode:8020/flink/savepoints/savepoint-abc123 ./app.jar ``` --- ## 🚫 什么情况下 State 无法恢复? | 情况 | 结果 | |------|------| | 没有开启 Checkpoint | ❌ 状态完全丢失 | | Checkpoint 存储在本地磁盘(如 `/tmp`) | ❌ 节点宕机后数据消失 | | HDFS/S3 路径权限不足或已删除 | ❌ 无法读取状态 | | 算子结构变更导致 UID 不匹配 | ❌ 状态映射失败(需兼容性处理) | --- ## ✅ 如何确保 killed 后能恢复? ### 步骤总结: 1. ✅ 在代码中启用 Checkpoint 并设置远程存储路径; 2. ✅ 使用 `RocksDBStateBackend` 或 `FileSystemStateBackend` 支持大状态; 3. ✅ 避免将状态存在本地文件系统; 4. ✅ (可选)定期打 Savepoint 用于人工干预恢复; 5. ✅ 重启时使用 `-s` 指定 Checkpoint 或 Savepoint 路径。 --- ## 📦 示例:完整配置 RocksDB + HDFS Checkpoint ```java StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 设置状态后端为 RocksDB,并存到 HDFS RocksDBStateBackend rocksDBStateBackend = new RocksDBStateBackend( "hdfs://namenode:8020/flink/checkpoints", CheckpointedFn.States.BEYOND_OPERATOR ); env.setStateBackend(rocksDBStateBackend); // 启用 Checkpoint env.enableCheckpointing(5000, CheckpointingMode.EXACTLY_ONCE); env.getCheckpointConfig().setMinPauseBetweenCheckpoints(2000); env.getCheckpointConfig().setCheckpointTimeout(60000); env.getCheckpointConfig().enableExternalizedCheckpoints( ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION ); // 重要:kill 后保留 Checkpoint ``` > ⚠️ `RETAIN_ON_CANCELLATION` 表示即使你 kill 作业,Checkpoint 文件也不会被自动删除,可用于后续恢复。 --- ## 🔄 重启命令建议 ```bash # 从特定 Checkpoint 恢复(推荐用于故障恢复) ./bin/flink run \ -s hdfs://namenode:8020/flink/checkpoints/<checkpoint-dir> \ ./my-streaming-job.jar # 或从 Savepoint 恢复(推荐用于升级) ./bin/flink run \ -s hdfs://namenode:8020/flink/savepoints/savepoint-abc123 \ ./my-streaming-job.jar ``` --- ## ✅ 总结 | 问题 | 回答 | |------|------| | Flink 被 killed 后 State 能恢复吗? | ✅ 可以,只要开启了 Checkpoint 并保存在可靠存储中 | | 需要哪些配置? | 启用 Checkpoint + 设置远程存储(HDFS/S3)+ 推荐 `RETAIN_ON_CANCELLATION` | | 如何手动恢复? | 使用 `flink run -s <path>` 指定 Checkpoint 或 Savepoint | | 不做任何配置会怎样? | ❌ 所有状态丢失,相当于重新开始计算 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值