flink容错机制(翻译官网英文文档)

  • 引言

flink提供了能够保持一致地恢复数据流应用的状态的一种容错机制,这种机制保证即使在故障持续发生的情况下,程序的状态最终依然会从数据流中产生并且保证exactly once,即正好一次的语义。

容错机制持续不断地从分布式数据流中提取snapshot快照,对于状态小small state的数据流应用,这些快照是非常轻量级的并且频繁的提取下不会对系统性能造成太大的影响。流应用的状态保存在一个可配置的持久化存储中(例如master节点,或者HDFS分布式文件系统中)。

一旦发生程序失效(由于机器,网络或者软件故障),flink停止整个分布式数据流,系统重启所有operators,并且将他们重置到最新的checkpoints。输入流被重置到状态快照点point of the state snapshot。任何重启的并发数据流中都保证不会是已经处理过的检查点状态中的数据流。

注意:默认情况下,checkpoint是关闭的。

注意:对这种机制来说,为了实现他的完整的保证,数据流源(例如massage queue或者massage broker)需要具备将数据流回退到最近定义的还原点的能力。kafka拥有这种能力,并且flink的connector利用了这种能力。

注意:由于flink检查点是通过分布式快照distributed snapshots的,所以我们将不区分快照snapshot和检查点checkpoint。

flink容错机制的中心内容是持续的提取分布式数据流和operator状态的快照。这些快照起的作用相当于作为系统一旦发生故障情况下用来回退的检查点。flink的机制在“lightweight asynchronous snapshots for distributed dataflows”这篇文章中有详述。它是源自于针对分布式快照的chandy-lamport 算法以及再根据flink编程模型进行修改而成的。 

  • 检查点
  • barriers(栅栏)

flink的分布式快照的核心元素是stream barriers,这些barriers被插入到数据流中,作为数据流的一部分和记录一起流动,barriers从来不会超过记录,在流中严格遵守流动顺序,一个barrier将数据流中的记录分成几部分,将一部分记录存入到当前的snapshot中,其他记录存入到下一个snapshot中。每个barrier携带snapshot 的ID,该snapshot将barrier之前的记录都存储了。barriers并不会打断数据流因此事轻量级的,多个来自不同snapshots的barriers可以同时存在于同一个数据流。这意味着不同的snapshots可以并发进行。

流barriers在流源头处被插入到并行数据流中,向流中插入barrier的位置取决于拍取数据的snapshot,例如,在kafka中,这个位置将会是划分部分的最后一条记录的偏移量。这个位置Sn将会报告给checkpoint协调器(job manager)
然后barrier向下流流动,当一个operator收到来自所有输入流的snapshot n 的barrier,他发射一个针对snapshot n 的barrier到它的所有输出流去。一旦一个sink operator接收到他来自输入流的所有barrier n,它会将snapshot n通知给checkpoint 协调器,当所有sinks都给checkpoint协调器通知了同一个snapshot,这时他就被认为已经完成。 

一旦snapshot n被完成,Sn之前的记录再也不用从source发送了,因为在那个时间这些记录已经完全流经了整个数据流拓扑。
 

接收到多个输入流的operator需要在snapshot barriers的输入流进行对齐,上面的图片说明了:

1. 一旦operator从即将到达的数据流接收到snapshot barrier n,直到他接收到其他所有输入流的barrier n之前,他不能再处理任何记录,否则,他会将属于snapshot n和n+1的记录混合。
2. 报告barrier n 的流将被暂时搁置,从其他流接收的记录将不会被处理,但是会放进一个输入缓存input buffer。
3. 一旦最后一个barrier n被接收到,operator立刻发送所有挂起需要向外发送的记录,然后发送它自己的snapshot n的barrier。
4. 执行完以后,它恢复处理来自所有输入流的记录,先处理输入缓存input buffer中的记录,再处理数据流中的记录。 

  • state

当operators包含state的任意形式,这个状态必须成为snapshot的一部分,operator的状态有以下几种形式:
1. 用户定义状态user-defined state:这个状态是由transformation function定义和修改的,(例如map()或者filter())
2. 系统状态system state:这个状态指的是作为operator 的计算结果的一部分的数据缓存。这种状态的一个典型的例子就是窗口缓存window buffer,在系统中,系统收集(并且聚合aggregate)窗口内的所有记录,直到窗口被计算和发送出去。

operators 当接收到所有输入流中的barrier以后就对他们的state 进行拍取快照,并且这发生在把barriers发送给输出流之前。在那时,所有在barrier之前对state所做的更新必须完成,并且不会产生依赖于barrier之后的记录的state的更新。由于snapshot的状态可能非常大,所以他会被存储在一个已配置的state backend中。默认情况下,是在jobmanager的内存中,但是为了严谨,应该使用一个分布式可靠存储,例如hdfs。state被存储之后,operator通知checkpoints,发送snapshot barrier到输出流中,然后继续执行。 

目前产生的snapshot包含:
每一个并行数据流源,数据流中snapshot开始的偏移量或者位置
每一个operator,指向state的指针作为snapshot的一部分存储在snapshot中
 

  • exactly once VS at least once

对其操作可能会给流程序增加延迟,有时,这个额外的延迟是微秒级的,但是也有延迟增加非常明显的情况。对于所有记录都需要持续低延迟的应用,flink可以在checkpoint过程中切换成无需对齐操作。此时只要一个operator从输入流中收到barrier就可以立即开始快照checkpoint snapshots。

当对齐操作被跳过,operator继续处理所有输入流,即使checkpoint n以后的barrier到达。这种方式下,operator也会在处理checkpoint n之前处理属于checkpoint n+1的数据,恢复的时候,这些记录会重复出现,因为他们同时存在于checkpoint n以及n以后的数据中。

注意:对齐仅仅发生在有多个前驱join和多个后继发送者repartition、shuffle的情况下,因为那种情况下,令人尴尬的是,数据流在只有一个并行数据流操作(map(), flatmap(), filter()......)情况下,即使在at least once模式中实际也只提供exactly once语义保证。

  • asynchronous state snapshots

以上描述的机制说明了operators当存储他们的state的snapshot到存储设备时会停止处理输入的记录,这种同步的状态快照每次都会导致延迟。

要使得operator在拍取快照的同时继续处理输入的记录,可以通过后端异步拍取快照。为了做到异步快照,operator必须能产生一个以某种方式存储的状态对象state object在进一步修改操作不受影响。例如,copy-on-write数据结构,这种数据结构被用在rocksDB中,就有这种性质。

当operators从它的输入流中接收到barriers以后,operator开始异步快照,拷贝他自己的状态,他立刻发送barrier到输出流中,继续常规流计算。一旦后台拷贝操作完成,他通知checkpoint协调器(jobmanager)。只有当所有sink operaror全部收到barrier并且所有stateful operator都通知协调器已经完成state拷贝(这些拷贝可能在barrier到达之后),checkpoint才算完成。

  • recovery

 这种容错机制下的恢复是直接的:一旦发生失效,flink选择最新的成功的checkpoint k。然后系统重新配置整个分布式数据流,给每个节点快照checkpoint k 中的一部分的状态state。数据源被设置成从Sk位置开始发送数据,例如,在kafka中,这意味着告诉用户开始从偏移量Sk的位置获取数据。

如果状态被增量快照,operaror将会从最新的快照开始,然后使用一系列增量snapshot更新到那个状态。

  • operator snapshot implementation

 当operator快照完成,有两部分:同步和异步。

operator 和state backend状态终端提供他们的snapshots作为java futuretask,这个任务包括完成的同步部分和挂起的异步部分的状态。然后异步部分作为那个checkpoint 的后台线程被执行。

完全同步的operator返回一个已经完成的futuretask,入股哦一个异步操作需要被执行,这个futuretask会执行run()方法。

任务是可取消的cancelable,所以数据流和其他被处理的资源能够被释放。

英文原文地址:https://ci.apache.org/projects/flink/flink-docs-release-1.5/internals/stream_checkpointing.html

猜你喜欢

转载自blog.csdn.net/zonahaha/article/details/81067379
今日推荐