Yhzhtk / note

知识代码笔记
https://github.com/Yhzhtk/note/issues
MIT License
108 stars 11 forks source link

Flink流计算容错机制 [译] #54

Open Yhzhtk opened 5 years ago

Yhzhtk commented 5 years ago

Introduction

Apache Flink提供容错机制来持续恢复数据流应用程序的状态(State)。 该机制确保即使在出现故障时,程序的状态最终可以恢复;在数据流里有两种级别的恢复保障,一是 exactly once,另一种是 at least once(下面会讲),他们可以通过开关调整。

容错机制不断绘制分布式流式数据流的快照。 对于状态较小的流式传输应用程序,这些快照非常轻,可以频繁绘制,而不会对性能产生太大影响。 流应用程序的状态存储位置可以配置(例如主节点或HDFS)。

如果程序失败(由于机器,网络或软件故障),Flink会停止分布式流式数据流。 然后系统重新启动运行节点(Operator)并将其重置为最新的成功检查点。 输入流被重置到状态快照记录的位置。 重新启动的并行数据流,只处理该快照检查点以后的记录,先前检查点状态之前的记录,不再处理(原文贴上,这句话不太好理解 Any records that are processed as part of the restarted parallel dataflow are guaranteed to not have been part of the previously checkpointed state.)。

注意:默认情况下,检查点(Checkpointing)被禁用。 有关如何启用和配置检查点的详细信息,请参阅 Checkpointing。

注意:为了实现其完全保证的此机制,数据流源(如消息队列或代理)需要能够将流重放到定义的最近点。 Apache Kafka有这种能力,而Flink的连接 Kafka 利用这种能力。 有关Flink连接器提供的保证的更多信息,请参阅数据源和接收器的容错保证。

注意:因为Flink的检查点是通过分布式快照实现的,所以我们可以互换地使用快照和检查点。

Checkpointing

Flink容错机制的核心部分是绘制分布式数据流和Operator状态的一致快照。 这些快照充当一致的检查点,在发生故障时系统可以回退。 Flink用于绘制这些快照的机制在“用于分布式数据流的轻量级异步快照”中进行了介绍。 它受分布式快照的标准Chandy-Lamport算法的启发,并专门为Flink的执行模型量身定制。

Barriers

Flink分布式快照的核心元素是流 Barrier。 这些 Barrier 被注入到数据流中,并作为数据流的一部分与记录一起流动。 Barrier 永远不会超过记录,流量严格符合要求。 Barrier 将数据流中的记录分成进入当前快照的记录集和进入下一个快照的记录。 每个 Barrier 都携带在其前面按下记录的快照的标识。 Barrier 不会中断流的流动,因此非常轻便。 来自不同快照的多个 Barrier 可以同时在流中,这意味着各种快照可以同时发生。

image

图:Checkpoint barriers in data streams

流 barrier 被注入流源处的并行数据流。 快照n的 barrier 被注入的位置(我们称之为Sn)是快照覆盖数据的源流中的位置。 例如,在Apache Kafka中,这个位置将是分区中最后一个记录的偏移量。 该位置Sn被报告给 checkpoint 协调器(Flink的JobManager)。

然后 barrier 流向下游。 当中间Operator从其所有输入流接收到快照n的 barrier 时,它会将快照n的 barrier 发射到其所有输出流中。 一旦 sink 操作(流式DAG结束)从所有输入流接收到 barrier n,它就会向 checkpoint 协调器确认快照n。 在所有接收器已经确认了快照之后,它被认为已完成。

一旦快照n完成,作业将永远不会再向Sn询问源,因为那时这些记录(及其后代记录)将已经通过整个数据流拓扑。

image

图:Aligning data streams at operators with multiple inputs

接收多个输入流的运算符需要对齐快照 barrier 上的输入流。 上图说明了这一点:

只要 operator 从输入流接收到快照 barrier n,它就不能处理来自该流的任何其他记录,直到它从其他输入接收到 barrier n为止。 否则,它会混合属于快照n的记录和属于快照n + 1的记录。 报告 barrier n的流暂时搁置。 从这些流收到的记录不会被处理,而是放入输入缓冲区。 一旦最后一个流接收到 barrier n,operator 发出所有待处理的传出记录,然后自己发出快照n operator。 之后,它从所有输入流中恢复处理记录,在处理来自流的记录之前处理输入缓冲区中的记录。

State

当运算符包含任何形式的状态时,该状态也必须是快照的一部分。 Operator 状态有不同的形式:

用户定义的状态:这是由转换函数(如map())或filter()))直接创建和修改的状态。 详情请参阅流媒体应用程序中的状态。 系统状态:该状态指的是作为运算符计算一部分的数据缓冲区。 这种状态的一个典型例子是窗口缓冲区,在窗口缓冲区中系统收集(并聚合)窗口的记录,直到窗口被评估和驱逐。 Operator 在他们收到来自输入流的所有快照 barrier 的时间点以及在将 barrier 排放到其输出流之前的时间点快照自己的状态。 在这一点上,从 barrier 出现之前的所有记录更新到状态,并且没有更新依赖于 barrier 应用后的记录。 由于快照的状态可能较大,因此它存储在可配置状态的后端。 默认情况下,这是JobManager的内存,但对于生产应用,应配置分布式可靠存储(如HDFS)。 在状态被存储之后,Operator确认检查点,将快照 barrier 发送到输出流并继续。

生成的快照现在包含:

对于每个并行流数据源,快照启动时流中的偏移量/位置 对于每个操作符,指向作为快照一部分存储的状态的指针

image

图:Illustration of the Checkpointing Mechanism

Exactly Once vs. At Least Once

对齐步骤可能会增加流媒体节目的延迟。 通常,这种额外的延迟大约为几毫秒,但我们已经看到一些异常值的延迟明显增加的情况。 对于所有记录需要持续超低延迟(几毫秒)的应用程序,Flink有一个开关,用于在检查点期间跳过流对齐。 只要Operator看到每个输入的检查点屏障,检查点快照仍会绘制。

当跳过对齐时,即使在检查点n的一些检查点 barrier 到达之后,Operator仍然继续处理所有输入。 这样,Operator在处理检查点n的状态快照之前也处理属于检查点n + 1的元素。 在还原时,这些记录将以重复的方式出现,因为它们都包含在检查点n的状态快照中,并将在检查点n之后作为数据的一部分重播。

注:对齐仅适用于具有多个前置器(joins)的Operator以及具有多个发送器的Operator(repartitioning/shuffle 之后)。 正因为如此,即使在至少一次模式下,仅使用令人尴尬的并行流操作(map()),flatMap()),filter())...)的数据流实际上也只能保证一次。

Asynchronous State Snapshots

请注意,上述机制意味着Operator在他们将状态的快照存储在状态后端时停止处理输入记录。 每次拍摄快照时,此同步状态快照都会引起延迟。

可以让Operator在存储其状态快照的同时继续处理,从而有效地让状态快照在后台异步发生。 要做到这一点,Operator必须能够生成一个状态对象,该状态对象应该以一种对Operator状态进行进一步修改不会影响该状态对象的方式进行存储。 例如,写时复制数据结构(如RocksDB中使用的数据结构)具有此行为。

在接收到输入端的检查点 barrier 后,Operator启动其状态的异步快照复制。 它立即消除了其输出的 barrier,并继续进行常规流处理。 一旦后台复制过程完成,它就会向检查点协调器(JobManager)确认检查点。 检查点现在只在所有 sink 接收到 barrier 并且所有有状态的Operator已经确认其完成的备份(可能在 barrier 达到 sink 之后)之后完成。

有关状态快照的详细信息,请参见状态后端

Recovery

这种机制下的恢复很简单:一旦失败,Flink选择最近完成的检查点k。 然后系统重新部署整个分布式数据流,并为每个Operator提供作为检查点k的一部分被快照的状态。 源被设置为开始从位置Sk读取流。 例如在Apache Kafka中,这意味着告诉消费者从偏移量Sk开始提取。

如果状态是增量快照,则Operator从最新的完整快照状态开始,然后对该状态应用一系列增量快照更新。

有关更多信息,请参阅重新启动策略

Operator Snapshot Implementation

采用Operator快照时,有两部分:同步部分和异步部分。

Operators和 state 后端将其快照作为Java FutureTask提供。 该任务包含同步部分完成且异步部分处于挂起状态。 然后异步部分由该检查点的后台线程执行。

Operator该检查点纯粹同步返回已完成的FutureTask。 如果需要执行异步操作,它将在该FutureTask的run() 方法中执行。

这些任务是可取消的,因此可以释放流和其他资源。

原文:Data Streaming Fault Tolerance (防止误导,所有的关键词'标题'都未翻译)