savepoints

什么是保存点?保存点和检查点的区别在哪
保存点是数据流的执行状态(一致的?),是通过检查点机制创建的。利用保存点可以停止和恢复,fork,或者更新任务。保存点由两部分组成:一个可靠存储上的文件路径(例如 hdfs,s3.。。),里面保存了二进制文件(通常比较大),还有一个元数据文件(相对小一些)。
可靠存储中的文件保存了job运行状态镜像的网络数据。保存点的元数据文件包括了(主要)可靠存储中全部文件的绝对路径。
注意:为了实现升级程序和flink版本,请查看下面的分配算子id这一节.
从概念上看,保存点与检查点的不同类似与传统数据库的备份和恢复日志的不同。检查点
最主要的目的是任务发生意外失败时可以提供恢复机制。flink管理检查点的生命周期,例如.
一个检查点的创建,生效,释放全部由flink控制,不需要用户参与。
作为一个周期性触发的恢复方法,检查点的实现需要满足两个主要的目标:
1)轻量的创建过程
2)尽可能快速的恢复过程
实现这些目标的优化可以利用某些属性,例如,job代码在多次执行期间不会变化。
任务被用户终止后,检查点通常被丢弃(除非显示的配置保留的检查点).
对比之下,保存点创建、生效、删除都是由用户控制。它们被用来计划性的手工备份和恢复。
例如,升级flink版本,改变作业流图,改变并行数,fork另个任务就像红蓝部署,等等。
当然,保存点必须在任务被终止之前执行。
从概念上,保存点允许创建、恢复、可移植性、支持前面提到的job变更上花费更高昂的代价。
抛开概念上的区别,当前的检查点和保存点实现基本上使用相同的代码并产生相同的输出内容。
尽管现在已经存在一个例外,后续还会介绍更多的区别。
这个例外是指增量检查点,基于RocksDB的状态存储.使用一些RocksDB的内部格式替代原生的flink savepoint格式。
相对于保存点,这是第一个实现更轻量检查点的机制。
分配算子id
本节描述了非常推荐的程序调整方式,已实现未来程序的升级更新。最主要的改变是通过uid方法手动指定算子id.
生成的id用来划分每个算子的状态。
DataStream 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不发生变化,保存点可以自动恢复算子状态。
自动生成的ID取决于程序的结构并且受程序改变的影响。因此推荐手工指定id。
保存点状态
保存点可以被认为是一个map表,每个有状态算子有一条从算子id到算子状态的记录
Operator ID | State
------------±-----------------------
source-id | State of StatefulSource
mapper-id | State of StatefulMapper
上面的例子里,输出算子是无状态算子,因此不在保存点状态中。
默认的,系统试着匹配保存点中的每条记录到新的程序中。

操作
在命令行可以触发保存点,执行保存点并退出,从保存点恢复,销毁保存点。
flink 1.2.0以上支持在webui里恢复保存点。

触发保存点
触发保存点时,新建一个保存点元数据文件的路径。可以通过修改默认目标路径或者通过命令行自定义目标路径。(查看targetDirectory参数)
注意:目标路径需要能同时被JobManager和TaskManager访问。例如使用分布式文件系统。

文件存储系统和RocksDB存储系统
#Savepoint target directory
/savepoints/

#Savepoint directory
/savepoints/savepoint-:shortjobid-:savepointid/

#Savepoint file contains the checkpoint meta data
/savepoints/savepoint-:shortjobid-:savepointid/_metadata

#Savepoint state
/savepoints/savepoint-:shortjobid-:savepointid/…

注意:尽管看似可以移动检查点,但当前并不支持,因为元数据中保存了文件的绝对路径。
请跟随FLINK-5778处理这个限制。

注意,当你使用内存MemoryStateBackend时,元数据和保存点状态同时被保存在元数据文件。
由于整个检查点是一个完整的整体,可以移动文件并保存在任意位置。

注意:避免移动或删除正在运行的job的最后保存点,因为这可能影响失败恢复。
保存点对精确一次的sink有副作用,因此为了确保精确一次的语义,如果保存点后没有检查点,保存点会被用作恢复。

触发保存点
$ bin/flink savepoint :jobId [:targetDirectory]
为指定jobid的任务触发保存点,返回创建的保存点路径。恢复任务或丢弃保存点时需要提供路径。

基于YARN触发保存点
$ bin/flink savepoint :jobId [:targetDirectory] -yid :yarnAppId
为指定jobid的任务和YARNId的应用触发保存点,返回创建的保存点路径。

取消任务并创建保存点
$ bin/flink cancel -s [:targetDirectory] :jobId
为指定jobid的任务触发保存点,然后取消任务。同时可以指定目标文件路径用来保存检查点。
JobManager和TaskManager能访问路径。

从保存点恢复
$ bin/flink run -s :savepointPath [:runArgs]
此操作提交一个从保存点恢复的job.指定元数据文件或保存点路径

允许未恢复状态
默认情况下恢复操作会把保存点状态全部匹配到程序算子。
如果删除了算子,允许跳过没有匹配新程序的状态。通过制定可选参数
–allowNonRestoredState(简化为-n)
$ bin/flink run -s :savepointPath -n [:runArgs]

丢弃保存点
$ bin/flink savepoint -d :savepointPath
丢弃路径对应的保存点
注意,通过文件系统直接删除保存点并不影响其它保存点或检查点(记得每个保存点时独立保存的)。

配置
通过state.savepoints.dir配置默认的保存点路径。
触发保存点时,路径被用来保存保存点。通过触发命令参数可以覆盖默认的目标路径。(查看:targetDirectory参数)
#Default savepoint target directory
state.savepoints.dir: hdfs:///flink/savepoints
未配置默认路径,命令也没有指定目标路径,触发保存点会失败。
注意:目标路径需要能被JobManager和TaskManager访问。

常见问题:
应该为任务里的每个算子分配id吗?
从经验来说,应该这样。严格的说,只需要通过uid方法为有状态算子分配id就足够了。
保存点只保存有状态算子的状态,无状态算子与保存点无关。
从实践的角度来看,推荐为所有算子分配id,因为一些内置算子例如winodw算子也存有状态,但是这些内置算子没有明显的区分出实际是否保存有状态。
如果确认一个算子完全无状态,那可以跳过uid方法。

向作业流图新增一个有状态的算子,会有哪些影响?
当添加一个新算子到作业时,算子初始化后不会有任何状态。保存点里面保存了每个有状态算子的状态。无状态算子不包含在保存点中。
新算子的行为与无状态算子是一致的。

从作业流图中删除一个有状态的算子,会有哪些影响?
默认,一个保存点恢复时会尝试将全部状态对应到恢复任务。如果恢复检查点中的状态对应的算子被删除,那么恢复因此失败。

可以设置命令参数允许状态不全部恢复 --allowNonRestoredState (简化:-n):
$ bin/flink run -s :savepointPath -n [:runArgs]

调整了作业流图中的有状态算子的顺序,会有哪些影响?
如果有状态的算子配置了ID,那么他们会正常恢复。
如果没有分配ID,在调整顺序后,有状态算子自动生成的ID很大几率会变化。这会导致你不能使用之前的保存点恢复它们的状态。

在作业流图上新增、删除或者调整无状态算子,会有哪些影响?
如果有状态的算子配置了ID,那么他们会正常恢复。
如果没有分配ID,在调整顺序后,有状态算子自动生成的ID很大几率会变化。这会导致你不能使用之前的保存点恢复它们的状态。

恢复状态时调整了并行数,会有哪些影响?
如果保存点是基于flink 1.2.0版本或以后,并且没使用弃用状态的api例如Checkpointed,你可以在恢复检查点同时指定新的并行数。
如果恢复的保存点是基于flink1.2.0版本以下或使用弃用状态的api,那么首先需要把任务和检查点迁移到flink1.2.0版本或之上,才能修改并行数。

可以将保存点文件移开稳定的存储吗?
最直接的回答是“否”,这是因为,由于技术上的原因元数据引用了保存在稳定存储的数据文件的绝对路径。
更详细的回答是:如果你由于某些原因必须移动这些文件,那么有两个方法可以作为解决方案。
第一个方法,简单但相对来说风险比较高,使用文件编辑器修改元数据文件中的路径为新文件路径。
另一个方法,使用SavepointV2Serializer类,用新路径以编程方式读取、操作和重写元数据文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值