flink Savepoint 和 Checkpoint 使用
- checkpoint
应用定时触发,用于保存状态,会过期
内部应用失败重启的时候使用,特点是作业容错自动恢复,轻量,自动周期管理 -
savepoint
用户手动执行,是指向Checkpoint的指针,不会过期
在升级的情况下使用,特点关注状态数据可以移植性,状态数据生成和恢复成本高,用户手动管理
注意:为了能够在作业的不同版本之间以及 Flink 的不同版本之间顺利升级,强烈推荐程序员通过 uid(String) 方法手动的给算子赋予 ID,这些 ID 将用于确定每一个算子的状态范围。如果不手动给各算子指定 ID,则会由 Flink 自动给每个算子生成一个 ID。只要这些 ID 没有改变就能从保存点(savepoint)将程序恢复回来。而这些自动生成的 ID 依赖于程序的结构,并且对代码的更改是很敏感的。因此,强烈建议用户手动的设置 ID。
生产环境下建议
对于有状态的 Flink 应用,推荐给每个算子都指定唯一用户ID(UUID)。 严格地说,仅需要给有状态的算子设置就足够了。但是因为 Flink 的某些内置算子(如 window)是有状态的,而有些是无状态的,可能用户不是很清楚哪些内置算子是有状态的,哪些不是。所以从实践经验上来说,我们建议每个算子都指定上 UUID。
Flink 算子的 UUID 可以通过 uid(String uid)
方法指定。算子 UUID 使得 Flink 有效地将算子的状态从 savepoint 映射到作业修改后(拓扑图可能也有改变)的正确的算子上,这是 savepoint 在 Flink 应用中正常工作的一个基本要素。
具体使用
savepoint
当触发 Savepoint 时,将创建一个新的 Savepoint 目录,其中存储数据和元数据。可以通过配置默认目标目录或使用触发器命令指定自定义目标目录(参见:targetDirectory参数来控制该目录的位置。
注意:目标目录必须是 JobManager(s) 和 TaskManager(s) 都可以访问的位置,例如分布式文件系统(或者对象存储系统)上的位置。
以 FsStateBackend 或 RocksDBStateBackend 为例:
# Savepoint 目标目录
/savepoint/
# Savepoint 目录
/savepoint/savepoint-:shortjobid-:savepointid/
# Savepoint 文件包含 Checkpoint元数据
/savepoint/savepoint-:shortjobid-:savepointid/_metadata
# Savepoint 状态
/savepoint/savepoint-:shortjobid-:savepointid/...
从 1.11.0 开始,你可以通过移动(拷贝)savepoint 目录到任意地方,然后再进行恢复。
在如下两种情况中不支持 savepoint 目录的移动:
1)如果启用了 *entropy injection:这种情况下,savepoint 目录不包含所有的数据文件,因为注入的路径会分散在各个路径中。 由于缺乏一个共同的根目录,因此 savepoint 将包含绝对路径,从而导致无法支持 savepoint 目录的迁移。
2)作业包含了 task-owned state(比如 GenericWriteAhreadLog
sink)。
和 savepoint 不同,checkpoint 不支持任意移动文件,因为 checkpoint 可能包含一些文件的绝对路径。
如果你使用 MemoryStateBackend
的话,metadata 和 savepoint 的数据都会保存在 _metadata
文件中,因此不要因为没看到目录下没有数据文件而困惑。
注意: 不建议移动或删除正在运行作业的最后一个 Savepoint ,因为这可能会干扰故障恢复。因此,Savepoint 对精确一次的接收器有副作用,为了确保精确一次的语义,如果在最后一个 Savepoint 之后没有 Checkpoint ,那么将使用 Savepoint 进行恢复。
触发 Savepoint
$ bin/flink savepoint :jobId [:targetDirectory]
这将触发 ID 为 :jobId 的作业的 Savepoint,并返回创建的 Savepoint 路径。 你需要此路径来还原和删除 Savepoint 。
使用 YARN 触发 Savepoint
$ bin/flink savepoint :jobId [:targetDirectory] -yid :yarnAppId
这将触发 ID 为 :jobId 和 YARN 应用程序 ID :yarnAppId 的作业的 Savepoint,并返回创建的 Savepoint 的路径。
使用 Savepoint 取消作业
$ bin/flink cancel -s [:targetDirectory] :jobId
这将自动触发 ID 为 :jobid 的作业的 Savepoint,并取消该作业。此外,你可以指定一个目标文件系统目录来存储 Savepoint 。该目录需要能被 JobManager(s) 和 TaskManager(s) 访问。
$ bin/flink run -s :savepointPath [:runArgs]
这将提交作业并指定要从中恢复的 Savepoint 。 你可以给出 Savepoint 目录或 _metadata 文件的路径。
跳过无法映射的状态恢复
默认情况下,resume 操作将尝试将 Savepoint 的所有状态映射回你要还原的程序。 如果删除了运算符,则可以通过 --allowNonRestoredState(short:-n)选项跳过无法映射到新程序的状态:
$ bin/flink run -s :savepointPath -n [:runArgs]
$ bin/flink savepoint -d :savepointPath
这将删除存储在 :savepointPath 中的 Savepoint。
请注意,还可以通过常规文件系统操作手动删除 Savepoint ,而不会影响其他 Savepoint 或 Checkpoint(请记住,每个 Savepoint 都是自包含的)。 在 Flink 1.2 之前,使用上面的 Savepoint 命令执行是一个更乏味的任务。
你可以通过 state.savepoints.dir 配置 savepoint 的默认目录。 触发 savepoint 时,将使用此目录来存储 savepoint。 你可以通过使用触发器命令指定自定义目标目录来覆盖缺省值。
# 默认 Savepoint 目标目录
state.savepoints.dir: hdfs:///flink/savepoints
如果既未配置缺省值也未指定自定义目标目录,则触发 Savepoint 将失败。
注意:目标目录必须是 JobManager(s) 和 TaskManager(s) 可访问的位置,例如,分布式文件系统上的位置。
1. 手动触发
flink作业jobid hdfs地址 yarn上执行的id
flink savepoint 4da2561ee17ef9e0bfa7dbd415585b03 hdfs://sss/flink/savepoints -yid application_1558494256595_52618
2. 从savepoint恢复,
关键参数--指定save检查点
flink run -m yarn-cluster -yn 2 -yjm 1024 -ytm 1024 -s hdfs://sss/flink/savepoints/savepoint-4da256-8d7d2f53bc9d -c mainclass flink-learn-1.0-SNAPSHOT-jar-with-dependencies.jar
checkpoint
使用方式
env.setStateBackend(new RocksDBStateBackend("hdfs://hadoop100:9000/flink/checkpoints",true));
-
当有taskmanager死掉了,可以自动容错,不用人工干预
本地checkpoint 恢复 check point 优化
-
相对于从hdsf网络获取,从本地更加快速,但是也会造成额外的开销,实现任务可以在本地启动,需要保存
每个任务的调度位置 Allocation-preserving scheduling
RocksDBStateBackend:密钥状态支持任务本地恢复。对于完整的检查点,状态被复制到本地文件。这会导致额外的写入成本并占用本地磁盘空间。对于增量快照,本地状态基于RocksDB的本机检查点机制。此机制也用作创建主副本的第一步,这意味着在这种情况下,创建第二副本不会引入额外的成本。我们只需保留本地检查点目录,而不是在上载到分布式存储后将其删除。此本地副本可以与RocksDB的工作目录共享活动文件(通过硬链接),因此对于活动文件,使用增量快照进行任务本地恢复也不会占用额外的磁盘空间。使用硬链接还意味着RocksDB目录必须与所有可用于存储本地状态的配置本地恢复目录位于同一物理设备上,否则建立硬链接可能会失败(请参阅FLINK-10954)。