一、什么是savepoint?
savepoint是通过checkpoint机制为streaming job创建的一致性快照,比如数据源offset,状态等。
需要我们手动去触发,因此,需要和checkpoint进行区分。checkpoint主要用于自动故障恢复,由Flink自动创建、拥有和发布,不需要用户去交互,当作业呗cancel的时候,checkpoint会被删除,除非设置了ExternalizedCheckpoint
的保留机制。
而savepoint由用户拥有,创建和删除,在作业停止后任然保存。它一般用于Flink版本升级更新,业务 迁移,集群需要迁移,不容许数据丢失。
通常为了后续作业的升级以及迁移之需,一般建议为程序的operator设置ID。可通过下面的方式来指定ID:
DataStream<String> stream = env.
// Stateful source (e.g. Kafka) with ID
.addSource(new StatefulSource())
.uid("source-id") // ID for the source operator
.shuffle()
// Stateful mapper with ID
.map(new StatefulMapper())
.uid("mapper-id") // ID for the mapper
// Stateless printing sink
.print(); // Auto-generated ID
如果不手动指定ID,那么系统会自动分配ID,只要ID不变就可以从指定的savepoint进行恢复,但是自动生成的ID依赖于程序结构,当程序改变时,ID会随之变化,所以建议手动指定。当我们指定ID后,那么savepoint就可以想象为一个operatorID->state
的映射。
二、触发savepoint
首先,我们需要指定一个savepoint的目录,使用下面参数来指定:
state.savepoints.dir: hdfs:///flink/savepoints
一般情况下,我们可以使用下面的命令来触发savepoint:
bin/flink savepoint :jobId [:targetDirectory]
如果是基于YARN搭建的集群,那么可以使用下面命令来触发:
bin/flink savepoint :jobId [:targetDirectory] -yid :yarnAppId
一般我们在进行savepoint之后,然后cancel这个job,下面这个命令可以在savepoint之后 自动cancel这个job,如下所示:
bin/flink cancel -s [:targetDirectory] :jobId
当我们需要使用savepoint进行恢复的时候,可以使用下面命令:
bin/flink run -s :savepointPath [:runArgs]
有时候在恢复的时候,会遇到一些不能映射的状态(上面提到可以将savepoint想象为一个ID->state的映射),例如删除了一个操作符,那么我们可以使用下面命令来跳过这个状态:
bin/flink run -s :savepointPath -n [:runArgs]
当然,我们还可以删除savepoint,使用下面命令即可:
bin/flink savepoint -d :savepointPath
参考资料:
https://ci.apache.org/projects/flink/flink-docs-release-1.6/ops/state/savepoints.html