Flink Program Guide (10) -- Savepoints (DataStream API编程指导 -- For Java)
Savepoint
本文翻译自文档Streaming Guide / Savepoints
-------------------------------------------------------------
使用DataStream API编写的程序可以从一个savepoint处恢复执行。savepoint可以同时更新你的程序和Flink集群而不丢失任何状态。该文档包括了从触发、存储以及销毁(dispose)savepoint的所有内容。有关Flink如何处理状态和失效的详细内容,请见文档State in Streaming Program和Fault Tolerance。
一、概述
savepoint是人工触发的检查点,它将对程序做一次快照并将结果写出到statebackend。这些过程都依赖于检查点机制。在程序执行期间,程序在worker节点处将进行周期性地快照并且生成检查点。由于恢复时仅仅需要最近的一个已完成的检查点,故旧的检查点在新的检查点完成后就可以安全地丢弃了。
savepoint类似于这些周期性的检查点,不同之处在于它们是由用户触发,并且不会在更新的检查点完成后自动过期。

在上图中的例子里,worker为job 0xA312BC生成了检查点c1,c2,c3。c4是最近的检查点,而c1和c3已经被抛弃。但c2是特殊的,它是与savepoint s1相关的状态并且已经被用户触发,且不会像c1和c3一样在更新的检查点完成后自动过期。
注意,s1仅仅是一个指向检查点数据c2的指针,这意味着实际上的savepoint的状态不是复制的并且周期性检查点是就近维护的(kept around)
二、配置
savepoint指向一个正常的检查点并且将它们的状态存储在配置好的StateBackend中。当前版本下,支持的state backend包括jobmanager和filesystem。有关周期性检查点的State backend的配置与savepoint的state backend是相互独立的。savepoint不是检查点数据的复制,但它会指向配置后的检查点state backend。
2.1 JobManager
这是savepoint的默认backend
savepoint存储在jobmanager的堆中,它们将在jobManager关闭时丢失。该模式仅仅在你想要在相同的集群持续运行的情况下将程序停止和恢复时才有用。不建议在产品级项目中使用该配置方式。savepoint不是"job manager的高度可用性状态"的一部分
savepoints.state.backend: jobmanager
注意,如果你不为savepoint配置一个state backend,则会使用JobManager的backend。
2.2 File system
在此配置中,savepoint将存储在配置的文件系统目录下。它在集群实例之间都是可用的并且允许你将程序移动到另一个集群上去。
savepoints.state.backend: filesystem
Savepoints.state.backend.fs.dir: hdfs:///flink/savepoints
注意:如果你不配置一个指定的目录,则会使用JobManager的backend
重要注意事项:一个savepoint是一个完整检查点的指针,这意味着savepoint的状态不仅仅会在savepoint文件本身中找到,还需要检查点的数据(例如在另一堆文件中)。因此,为savepoint使用filesystem backend而为检查点使用jobmanager backend并不能发挥作用,这是因为在JobManager重启之后就无法请求道检查点数据了。
三、用户程序的修改
savepoint是开箱即用的,但我们强烈建议你轻度地调整你的程序以使其可以在程序未来的版本中仍可以使用savepoint。

对于savepoint来说,只有有状态的Task才重要。在上面的例子中,source和map的task是有状态的,而sink是无状态的,因此,只有source和map的task才会属于savepoint范围之内。
每个Task都使用生成的Task ID和subtask index来进行标识。在上面的例子中source(s1,s2)的状态以及map(m1.m2)的状态是由对应task ID(source Task是0xC322EC,而map task是0x27B3EF)和subtask index标识的。而sink(t1,t2)没有状态,因此他们的ID并没有用。
重要注意事项:ID是从你的程序结构中确切(deterministically)生成的,这意味着只要你的程序不发生改变,这些ID也不会改变。只有用户方法内才允许改变,例如你可以在不改变topology的前提下修改MapFunction的实现。在这种情况下,在从savepoint恢复程序时,我们可以直接将状态映射到相同的task ID和subtask index处便是一个。该方法使得你可以开箱即用savepoint,但是这回在你改变topology时产生问题,因为这将导致ID的变化,从而使你无法再将savepoint状态映射到你的程序。
建议:为了修改你的程序并且拥有固定的ID,DataStream API提供了方法来人工指定task ID。每个Operator都提供了uid(String)的方法来覆盖生成的ID。ID是一个字符串,它将决定性地hash到一个16byte的哈希值。对每个transformation和job都拥有唯一的ID是非常重要的,如果不唯一,则job的提交将会失败。
DataStream<String> stream = env.
// Stateful source (e.g. Kafka) with ID
.addSource(new StatefulSource())
.uid("source-id")
.shuffle()
// The stateful mapper with ID
.map(new StatefulMapper())
.uid("mapper-id")
//
Stateless sink (no specific ID required)
stream.print()
四、命令行客户端
你可以通过command line client控制savepoint
五、目前版本的局限性
·
并行度:在恢复一个savepoint时,程序的并行度需要与生成savepoint的原程序的并行度匹配,目前还没有机制来为savepoint的状态进行重新分区(re-partition)。
·
链接(chaining):链接Operator通过第一个task的ID标识,为一个链接的task的中间task人工赋值一个ID是不可能的。例如链接[ a ->
b -> c]中只有a可以拥有人工赋值的ID,而b和c不行。若要绕开这个问题,你可以人工定义任务链接。如果你依靠的是自动ID赋值,对链接行为的改变同样会引起ID的改变。
·
销毁自定义状态handle:销毁旧的savepoint无法用于自定义state
handles(如果你增在使用自定义state
backend的话),这是因为用户代码的class
loader在disposal时是不可用的。
Flink Program Guide (10) -- Savepoints (DataStream API编程指导 -- For Java)的更多相关文章
- Flink Program Guide (2) -- 综述 (DataStream API编程指导 -- For Java)
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...
- Flink Program Guide (8) -- Working with State :Fault Tolerance(DataStream API编程指导 -- For Java)
Working with State 本文翻译自Streaming Guide/ Fault Tolerance / Working with State ---------------------- ...
- Flink Program Guide (3) -- Event Time (DataStream API编程指导 -- For Java)
Event Time 本文翻译自DataStream API Docs v1.2的Event Time ------------------------------------------------ ...
- Flink Program Guide (6) -- 窗口 (DataStream API编程指导 -- For Java)
窗口(Window) 本文翻译自文档Windows ----------------------------------- Flink使用窗口的概念,根据element的时间戳或者其他指标,将可能无限 ...
- Flink Program Guide (7) -- 容错 Fault Tolerance(DataStream API编程指导 -- For Java)
false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-n ...
- Flink Program Guide (5) -- 预定义的Timestamp Extractor / Watermark Emitter (DataStream API编程指导 -- For Java)
本文翻译自Pre-defined Timestamp Extractors / Watermark Emitter ------------------------------------------ ...
- Flink Program Guide (4) -- 时间戳和Watermark生成(DataStream API编程指导 -- For Java)
时间戳和Watermark生成 本文翻译自Generating Timestamp / Watermarks --------------------------------------------- ...
- Flink Program Guide (1) -- 基本API概念(Basic API Concepts -- For Java)
false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-n ...
- Flink Program Guide (9) -- StateBackend : Fault Tolerance(Basic API Concepts -- For Java)
State Backends 本文翻译自文档Streaming Guide / Fault Tolerance / StateBackend ----------------------------- ...
随机推荐
- .NET进阶系列之一:C#正则表达式整理备忘
有一段时间,正则表达式学习很火热很潮流,当时在CSDN一天就能看到 好几个正则表达式的帖子,那段时间借助论坛以及Wrox Press出版的<C#字符串和正则表达式参考手册>学习了一些基础的 ...
- TableLayout属性
整理于http://naotu.baidu.com/file/e5880b84b1a906838116f7a45f58de78
- Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to “*****”
Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment ...
- Java IO流分析整理 .
Java中的流,可以从不同的角度进行分类. 按照数据流的方向不同可以分为:输入流和输出流. 按照处理数据单位不同可以分为:字节流和字符流. 按照实现功能不同可以分为:节点流和处理流. 输出流: 输入流 ...
- 安装Ubuntu时的硬盘分区方案 转载
安装Ubuntu时的硬盘分区方案 http://www.cnblogs.com/shenliang123/p/3196743.html 如果你准备在硬盘里只安装Ubuntu一个操作系统的话,建议你采用 ...
- groovy 弹出菜单
import groovy.swing.* import javax.swing.* import java.awt.* def swing = new SwingBuilder() swing.fr ...
- IEnumerable
C#基础之IEnumerable 1.IEnumerable的作用 在使用Linq查询数据时经常以IEnumerable<T>来作为数据查询返回对象,在使用foreach进行遍历时需要该对 ...
- Google map v3 using simple tool file google.map.util.js v 1.1
/** * GOOGLE地图开发使用工具 * @author BOONYACHENGDU@GMAIL.COM * @date 2013-08-23 * @notice 地图容器的z-index不能小于 ...
- poj 1083 Moving Tables_dp
题意:给你n个凳子,接着告诉你一个凳子从a房间到b房间,运输时间为10分钟,走廊很窄能通过一张凳子,当然不堵塞的话能同时扮凳子,问最小花费多少时间 因为数据很小就直接用数组统计了,a,b如果是奇数的话 ...
- 十个JAVA程序员容易犯的错误
十个JAVA程序员容易犯的错误 1. Array 转 ArrayList 一般开发者喜欢用: List<String> list = Arrays.asList(arr); Arrays. ...