Apache Flink Savepoint管理工具:创建/删除/恢复全流程
【免费下载链接】flink 项目地址: https://gitcode.com/gh_mirrors/fli/flink
什么是Savepoint(保存点)
Savepoint是Flink流处理作业执行状态的一致性镜像,通过Flink的检查点机制创建。它主要用于作业的有计划停机、升级或迁移场景,可实现作业的精确恢复。Savepoint由两部分组成:存储在稳定存储(如HDFS、S3)上的二进制文件目录和一个元数据文件,元数据文件包含指向所有数据文件的相对路径指针。
与自动管理的检查点(Checkpoint)不同,Savepoint由用户完全控制其生命周期,Flink不会自动删除Savepoint,即使在作业终止后也是如此。关于两者的详细区别,请参考检查点与Savepoint对比。
操作前准备:为算子分配ID
为确保Savepoint的可移植性和版本兼容性,强烈建议通过uid(String)方法为所有有状态算子指定唯一ID,这些ID用于限定每个算子的状态作用域。
DataStream<String> stream = env
// 为有状态源算子指定ID
.addSource(new StatefulSource())
.uid("source-id")
.shuffle()
// 为有状态映射算子指定ID
.map(new StatefulMapper())
.uid("mapper-id")
// 无状态打印算子不需要ID
.print();
如果不手动指定ID,Flink会自动生成ID,但这些ID依赖于程序结构,对代码变更非常敏感,可能导致无法从旧的Savepoint恢复。
Savepoint文件格式
Flink支持两种Savepoint二进制格式:
-
标准格式(canonical format):统一的跨状态后端格式,可在不同状态后端间迁移,是最稳定的格式,确保与之前版本的最大兼容性。这是Flink 1.15之前的默认格式。
-
原生格式(native format):特定于所用状态后端的格式(如RocksDB的SST文件),创建和恢复速度更快,但不支持跨状态后端迁移。自Flink 1.15起支持。
Savepoint操作全流程
1. 创建Savepoint
创建Savepoint时会生成一个新目录,用于存储数据和元数据文件。目标目录可以通过配置默认目录或在触发命令中指定自定义目录。
基本命令格式
$ bin/flink savepoint :jobId [:targetDirectory]
示例:创建标准格式Savepoint
$ bin/flink savepoint 71be70f08b7b4e92bf52c7569e7a3523 hdfs:///flink/savepoints
该命令会为ID为71be70f08b7b4e92bf52c7569e7a3523的作业创建Savepoint,并返回创建的Savepoint路径,例如:hdfs:///flink/savepoints/savepoint-71be70-bb1e257f0dab,此路径用于后续的恢复和删除操作。
示例:创建原生格式Savepoint
$ bin/flink savepoint --type native 71be70f08b7b4e92bf52c7569e7a3523 hdfs:///flink/savepoints
处理大状态作业: detached模式
当作业状态较大时,客户端可能因等待超时而失败,此时可使用detached模式触发Savepoint,客户端会立即返回触发ID,之后可通过REST API查询状态:
$ bin/flink savepoint 71be70f08b7b4e92bf52c7569e7a3523 hdfs:///flink/savepoints -detached
Triggering savepoint in detached mode for job 71be70f08b7b4e92bf52c7569e7a3523.
Successfully trigger manual savepoint, triggerId: 2505bbd12c5b58fd997d0f193db44b97
可通过REST API监控Savepoint状态:
GET /jobs/:jobid/checkpoints/triggerid/:triggerid
2. 从Savepoint恢复作业
使用run命令提交作业时,通过-s或--fromSavepoint参数指定Savepoint路径即可从Savepoint恢复作业。
基本恢复命令
$ bin/flink run -s :savepointPath [:runArgs]
例如,从之前创建的Savepoint恢复作业:
$ bin/flink run \
--detached \
-s hdfs:///flink/savepoints/savepoint-71be70-bb1e257f0dab \
./examples/streaming/StateMachineExample.jar
允许跳过无法恢复的状态
如果新作业删除了某些旧作业中的算子,恢复时需要使用--allowNonRestoredState(简写-n)选项允许跳过无法映射的状态:
$ bin/flink run \
-s hdfs:///flink/savepoints/savepoint-71be70-bb1e257f0dab \
-n \
./examples/streaming/StateMachineExample.jar
所有权声明模式(Claim Mode)
恢复时可通过--claimMode参数指定Savepoint文件的所有权模式,决定谁接管Savepoint文件的所有权:
- NO_CLAIM(默认):Flink不取得所有权,用户可手动删除,首次检查点将强制为完整检查点
- CLAIM:Flink取得所有权,将Savepoint视为检查点管理,可能在不需要时删除
- LEGACY(已弃用):Flink 1.15之前的行为,所有权不明确
$ bin/flink run \
-s :savepointPath \
--claimMode CLAIM \
-n [:runArgs]
3. 删除Savepoint
使用savepoint命令配合--dispose选项可删除不再需要的Savepoint:
基本删除命令
$ bin/flink savepoint --dispose :savepointPath :jobId
例如:
$ bin/flink savepoint \
--dispose \
hdfs:///flink/savepoints/savepoint-71be70-bb1e257f0dab \
71be70f08b7b4e92bf52c7569e7a3523
处理自定义状态实例
如果Savepoint包含自定义状态实例(如自定义ReducingState或RocksDB状态),删除时需要指定创建Savepoint时使用的程序JAR:
$ bin/flink savepoint \
--dispose <savepointPath> \
--jarfile <jarFile>
配置默认Savepoint目录
可通过配置文件或代码设置默认的Savepoint目标目录,避免每次操作都指定目录。
通过配置文件设置
在flink-conf.yaml中添加:
execution.checkpointing.savepoint-dir: hdfs:///flink/savepoints
通过代码设置
// Java
env.setDefaultSavepointDir("hdfs:///flink/savepoints");
// Scala
env.setDefaultSavepointDir("hdfs:///flink/savepoints")
常见问题解答
Q: 是否需要为所有算子分配ID?
A: 建议为所有算子分配ID。严格来说,只需为有状态算子分配,但Flink的一些内置算子(如Window算子)也是有状态的,为避免遗漏,最好为所有算子分配ID。
Q: 添加新的有状态算子会影响从旧Savepoint恢复吗?
A: 不会。新添加的算子会以无状态方式初始化,不影响现有状态的恢复。
Q: 能否移动Savepoint文件到其他位置?
A: 标准格式的Savepoint是自包含且可重定位的,可以移动整个Savepoint目录到其他位置,然后从新位置恢复。原生格式的Savepoint同样支持重定位。
Q: 从Savepoint恢复时可以修改作业并行度吗?
A: 可以。恢复时直接指定新的并行度即可,Flink会自动处理状态的重分配。
Savepoint管理最佳实践
- 定期创建Savepoint:特别是在重大更新前,作为数据安全保障
- 使用有意义的目录命名:如包含作业名、日期和版本信息
- 测试恢复流程:确保Savepoint实际可用于恢复
- 清理不再需要的Savepoint:避免存储空间耗尽
- 监控Savepoint大小:过大的Savepoint可能影响性能
- 结合Checkpoint使用:Checkpoint用于故障恢复,Savepoint用于计划维护
通过合理使用Savepoint,可实现Flink作业的无缝升级、弹性扩展和数据安全保障,是构建可靠流处理系统的关键组件。
【免费下载链接】flink 项目地址: https://gitcode.com/gh_mirrors/fli/flink
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



