检查点
检查点的保存
最理想的情况是,每处理完一个数据就保存一下当前的状态,但是这样处理效率不高。
- 周期性的触发保存:每隔一段时间去做一次存档,间隔时间可以进行设置。
- 保存的时间点:当所有任务都恰好处理完一个相同的输入数据的时候,将它们的状态保存下来。如果出现故障,我们恢复到之前保存的状态,故障时正在处理的所有数据都需要重新处理,所以只需要让源任务向数据源重新提交偏移量、请求重放数据就可以了
恢复状态
在运行流处理程序时,Flink 会周期性地保存检查点。当发生故障时,就需要找到最近一次成功保存的检查点来恢复状态。
这里 Source 任务己经处理完毕,所以偏移量为5;Map任务也处理完成了。而Sumn任务
在处理中发生了故障,此时状态并未保存。
- 重启应用,所有状态都会清空。
- 读取检查点,重置状态。
- 重放数据,通过 Source 任务向外部数据源重新提交偏移量来实现。
- 修复完成,继续处理数据。
想要正确地从检查点中读取并恢复状态,必须知道每个算子任务状态的类型和它们的先后顺序。状态的拓扑结构在 JobManager 上,可以由 JobGraph 分析得到,而检查点保存的定期触发也是由 JobManager 控制的,所以故障恢
复的过程需要 JobManager 的参与。
检查点算法
- 检查点分界线:在不暂停流处理的前提下,让每个任务“认出”触发检查点保存的那个数据。在数据流中插入一个特殊的数据结构,专门用来表示触发检查点保存的时间点。到保存检查点的指令后,Source 任务可以在当前 数据流中插入这个结构,之后的所有任务只要遇到它就开始对状态做持久化快照保存。
- 分布式快照算法:当上游任务向多个并行下游任务发送 barrier 时,需要广播出去,而当多个上游任务向同一个下游任务传递 barrier 时,需要在下游任务执行分界线对齐操作。
检查点配置
- 启用检查点:显式地调用执行环境的
enableCheckpointing()
方法。 - 检查点存储:检查点具体的持久化存储位置。默认情況下,检查点存储在 JobManager 的堆内存中。可以通过调用检查点配置的
setCheckpointStorage()
来配置,需要传入一个CheckpointStorage
的实现类。- 作业管理器的堆内存
- 文件系统
保存点
除了检查点外,Flink 还提供了另一个非常独特的镜像保存功能—保存点。它的原理和算法与检查点完全相同,只是多了一些额外的元数据。事实上,保存点就是通过检查点的机制来创建流式作业状态的一致性镜像的。
保存点中的状态快照,是以算子 ID 和状态名称组织起来的,相当于一个键值对。从保存点启动应用程序时,Flink 会将保存点的状态数据重新分配给相应的算子任务。
检查点是由 Flink 自动管理的,定期创建,发生故障之后自动读取进行恢复。而保存点不会自动创建,必须由用户明确地手动触发保存操作。
保存点中状态都是以算子 ID - 状态名称这样的 KV 组织起来的,对于没有设置 ID 的算子,Flink 默认会自动进行设置,所以在重新启动应用后可能会导致 ID 不同而无法兼容以前的状态。所以为了方便后续的维护,强烈建议在程序中为每一个算子手幼指定ID。
DataStream<String> stream = env
.addSource(new StatefulSource())
.uid("source-id")
.map(new StatefulMapper())
.uid("mapper-id")
.print();
状态一致性
一致性其实就是结果的正确性。对于分布式系统而言,强调的是不同节点中相同数据的副本应该总是“一致的”。
- AT-MOST-ONCE:当任务故障时,最简单的做法是什么都不干,既不恢复丢失的状态,也不重播丢失的数据。
- AT-LEAST-ONCE:至少保证数据不丢,所有的事件都得到了处理,而一些事件还可能被处理多次。
- EXACTLY-ONCE:。恰好处理一次语义不仅仅意味着没有事件丢失,还意味着针对每一个数据,内部状态仅仅更新一次。
端到端状态一致性
端到端的一致性保证,意味着结果的正确性贯穿了整个流处理应用的始终,每一个组件都保证了它自己的一致性。整个端到端的一致性级别取决于所有组件中一致性最弱的组件。
标签:状态,Flink,保存,容错,任务,检查点,一致性,机制 From: https://www.cnblogs.com/fireonfire/p/17019958.html