有状态流处理#
什么是状态?#
虽然数据流中的许多操作只是查看一个个体一次事件(例如事件解析器),有些操作会记住多个事件的信息(例如窗口操作符)。这些操作被称为宏伟威严的.
有状态操作的一些例子:
当应用程序搜索某些事件模式时,状态将存储到目前为止遇到的事件序列。
当聚合每分钟/小时/天的事件时,状态会保存挂起的聚合。
当在数据点流上训练机器学习模型时,状态保存模型参数的当前版本。
当需要管理历史数据时,国家允许高效地访问过去发生的事件。
Flink需要知道状态,以便使用检查站和保存点.
关于状态的知识还允许重新调整Flink应用程序的规模,这意味着Flink负责在并行实例之间重新分配状态。
可查询状态允许您在运行时从Flink外部访问状态。
使用state时,阅读以下内容可能会有所帮助弗林克州后端。Flink提供了不同的状态后端,指定状态存储的方式和位置。
返回页首
键控状态#
键控状态在可以被认为是嵌入式键/值存储中维护。状态与有状态操作符读取的流一起被严格分区和分发。因此,对键/值状态的访问只能在键控流,即在键控/分区数据交换之后,并且限于与当前事件的键相关联的值。对齐流和状态的键可以确保所有状态更新都是本地操作,从而保证一致性而不会产生事务开销。这种对齐还允许Flink透明地重新分配状态和调整流分区。
State and Partitioning
键控状态被进一步组织成所谓的关键群体。密钥组是Flink重新分配密钥状态的原子单元;关键组的数量与定义的最大并行度完全相同。在执行过程中,键控运算符的每个并行实例都使用一个或多个键组的键。
状态持久性#
Flink使用以下组合来实现容错流重放和检查点。检查点标记每个输入流中的特定点以及每个操作符的相应状态。流式数据流可以从检查点恢复,同时保持一致性(恰好一次处理语义)通过恢复操作员的状态并从检查点重放记录。
检查点间隔是一种在执行期间容错开销与恢复时间(需要重放的记录数量)之间进行权衡的方法。
容错机制持续绘制分布式流式数据流的快照。对于具有小状态的流应用程序,这些快照非常轻量,可以频繁绘制而不会对性能产生太大影响。流式应用程序的状态存储在可配置的位置,通常存储在分布式文件系统中。
如果程序出现故障(由于机器故障、网络故障或软件故障),Flink会停止分布式数据流。然后,系统重新启动操作符,并将它们重置为最近一次成功的检查点。输入流被重置到状态快照点。作为重新启动的并行数据流的一部分处理的任何记录都保证不会影响先前的检查点状态。
默认情况下,检查点是禁用的。看见检查点有关如何启用和配置检查点的详细信息。
为了实现这种机制的完全保证,数据流源(如消息队列或代理)需要能够将流回滚到一个定义的最近点。阿帕奇卡夫卡有这种能力,而弗林克与卡夫卡的连接就利用了这一点。看见数据源和接收器的容错保证有关Flink连接器提供的担保的更多信息。
因为Flink的检查点是通过分布式快照实现的,所以我们使用以下词语快照和检查站可互换。我们也经常使用这个术语快照意味着要么检查站或者保存点.
检查点#
Flink容错机制的核心部分是绘制分布式数据流和操作员状态的一致快照。这些快照充当一致的检查点,系统可以在出现故障时回退到这些检查点。Flink绘制这些快照的机制在“分布式数据流的轻量级异步快照".它受到标准的启发昌迪-兰波特算法用于分布式快照,并专门针对Flink的执行模型量身定制。
请记住,与检查点相关的所有事情都可以异步完成。检查点障碍不在锁定步骤中行进,操作可以异步地拍摄它们的状态。
从Flink 1.11开始,检查点可以对齐也可以不对齐。在本节中,我们首先描述对齐的检查点。
障碍#
Flink分布式快照的核心元素是河流障碍。这些障碍被注入到数据流中,并作为数据流的一部分与记录一起流动。障碍永远不会超越记录,它们严格地排成一行。一个屏障将数据流中的记录分为进入当前快照的记录集和进入下一个快照的记录。每个障碍都带有快照的ID,该快照的记录被推到它的前面。栅栏不会中断水流,因此重量很轻。来自不同快照的多个障碍可以同时出现在流中,这意味着各种快照可能会并发发生。
Checkpoint barriers in data streams
流障碍被注入到流源处的并行数据流中。快照的障碍点n被注射(姑且称之为Sn)是源数据流中快照覆盖数据的位置。例如,在Apache Kafka中,这个位置将是分区中最后一个记录的偏移量。这个位置Sn向报告检查站协调员(Flink的JobManager)。
然后屏障流向下游。当中间操作员接收到快照的障碍时n从它的所有输入流中,它发出一个快照屏障n流入所有流出的溪流。一旦接收操作者(流式DAG的末端)接收到屏障n从它的所有输入流中,它确认该快照n给检查站协调员。所有接收器确认快照后,即视为完成。
一次快照n已经完成,作业将不再向源请求以前的记录Sn,因为此时这些记录(及其后代记录)将已经通过了整个数据流拓扑。
Aligning data streams at operators with multiple inputs
接收多个输入流的运营商需要排列快照屏障上的输入流。上图说明了这一点:
一旦操作员收到快照屏障n从传入的流中,它不能处理来自该流的任何进一步的记录,直到它接收到该屏障n从其他输入中分离出来。否则,它会混合属于快照的记录n以及属于快照的记录n+1.
一旦最后一个流受到阻碍n,运算符发出所有挂起的传出记录,然后发出快照n壁垒本身。
它拍摄状态快照并继续处理来自所有输入流的记录,在处理来自流的记录之前处理来自输入缓冲区的记录。
最后,操作员将状态异步写入状态后端。
请注意,对于具有多个输入的所有操作符,以及在一次洗牌后消耗多个上游子任务的输出流的操作符,都需要对齐。
快照操作员状态#
当运算符包含任何形式的状态,此状态也必须是快照的一部分。
操作员在接收到来自其输入流的所有快照障碍时,以及在向其输出流发射障碍之前,对其状态进行快照。此时,所有来自障碍前记录的状态更新都已完成,并且没有依赖于障碍应用后记录的更新。因为快照的状态可能很大,所以它存储在可配置的状态后端。默认情况下,这是作业管理器的内存,但对于生产使用,应配置分布式可靠存储(如HDFS)。存储状态后,操作员确认检查点,将快照屏障发送到输出流中,然后继续。
生成的快照现在包含:
对于每个并行流数据源,快照启动时流中的偏移量/位置
对于每个操作符,指向作为快照的一部分存储的状态的指针
Illustration of the Checkpointing Mechanism
恢复#
这种机制下的恢复很简单:失败时,Flink选择最近完成的检查点k。然后,系统重新部署整个分布式数据流,并为每个操作员提供作为检查点一部分拍摄的状态k。源被设置为从位置开始读取流Sk。例如,在Apache Kafka中,这意味着告诉消费者从偏移量开始获取Sk.
如果状态是增量拍摄的,则操作员从最新完整快照的状态开始,然后对该状态应用一系列增量快照更新。
看见重启策略了解更多信息。
未对齐的检查点#
检查点也可以在不对齐的情况下执行。基本思想是检查点可以取代所有正在进行的数据,只要正在进行的数据成为操作符状态的一部分。
注意,这种方法实际上更接近于昌迪-兰波特算法,但是Flink仍然在源中插入屏障以避免检查点协调器过载。
Unaligned checkpointing
该图描述了操作员如何处理未对齐的检查点障碍物:
操作员对存储在其输入缓冲区中的第一个障碍做出反应。
它通过将障碍添加到输出缓冲区的末尾,立即将其转发给下游操作符。
操作符将所有被超越的记录标记为异步存储,并创建其自身状态的快照。
因此,操作员只需短暂停止输入处理以标记缓冲区、转发屏障并创建另一状态的快照。
未对齐的检查点确保障碍尽快到达接收器。它特别适合至少有一条缓慢移动的数据路径的应用程序,在这些应用程序中,对齐时间可能长达数小时。然而,由于它增加了额外的I/O压力,当状态后端的I/O成为瓶颈时,它并没有帮助。请参阅中更深入的讨论工作对于其他限制。
请注意,保存点将始终保持一致。
未对齐恢复#
操作员首先恢复运行中的数据,然后开始处理来自上游操作员的未对齐检查点的任何数据。除此之外,它还执行与期间相同的步骤恢复对齐的检查点.
状态后端#
存储键/值索引的确切数据结构取决于所选择的状态后端。一个状态后端将数据存储在内存中的哈希映射中,另一个状态后端使用RocksDB作为键/值存储。除了定义保存状态的数据结构之外,状态后端还实现了获取键/值状态的时间点快照并将该快照存储为检查点的一部分的逻辑。状态后端可以在不改变应用程序逻辑的情况下配置。
checkpoints and snapshots
返回页首
保存点#
所有使用检查点的程序都可以从保存点。保存点允许在不丢失任何状态的情况下更新您的程序和Flink集群。
保存点是手动触发的检查点,它获取程序的快照并将其写入状态后端。为此,他们依赖常规的检查点机制。
保存点类似于检查点,除了它们是由用户触发和不要自动过期当更新的检查点完成时。为了正确使用保存点,了解检查站 与 保存点之间的区别非常重要,检查站与保存点中对此进行了描述。
返回页首
恰好一次与至少一次#
对准步骤可能会给流式节目增加等待时间。通常,这种额外的延迟是几毫秒的量级,但我们已经看到一些异常值的延迟明显增加的情况。对于要求所有记录持续超低延迟(几毫秒)的应用程序,Flink有一个开关可以在检查点期间跳过流对齐。一旦操作员从每个输入中看到检查点障碍,仍然会绘制检查点快照。
当对齐被跳过时,操作者继续处理所有输入,甚至在一些检查点的检查点障碍之后n到了。这样,操作符也处理属于检查点的元素n+1检查点的状态快照之前n被带走了。在恢复时,这些记录将作为副本出现,因为它们都包含在检查点的状态快照中n,并将在检查点后作为数据的一部分重放n.
只有具有多个前置(连接)的运算符以及具有多个发送方的运算符才会发生对齐(在流重新分区/混洗之后)。正因为如此,数据流只有令人尴尬的并行流操作(map(), flatMap(), filter(),…)其实给正好一次保证即使在至少一次模式。
返回页首
批处理程序中的状态和容错#
弗林克执行批处理程序作为流式节目的特殊情况,其中流是有界的(有限数量的元素)。A资料组在内部被视为数据流。因此,上述概念适用于批处理程序的方式与它们适用于流式程序的方式相同,除了一些小的例外:
批处理程序的容错不使用检查点。通过完全重放流来进行恢复。这是可能的,因为输入是有界的。这将成本更多地推向恢复,但使常规处理更便宜,因为它避免了检查点。
数据集API中的有状态操作使用简化的内存/核外数据结构,而不是键/值索引。
DataSet API引入了特殊的同步(基于超步的)迭代,这种迭代只可能在有界流上进行。有关详细信息,请查看迭代文档.
标签:状态,快照,barrier,Flink,检查点,数据流,对齐 From: https://www.cnblogs.com/huft/p/18249362