1 回顾

上一篇文章对Flink如何保证一致性进行了说明,exactly-once一致性为Flink应用场景提供了正确性保证。先来回顾一下:

ckpt是Flink实现exactly-once一致性保证的核心。同时ckpt对性能的影响也较小,这为低延迟、高可靠性应用提供了坚实的基础。基于ckpt机制的手动svpt机制,为计算系统的演进提供了灵活的实现方式。

Flink为计算一致性提供exactly-once保证,这是

2 一致性分类

分布式系统引入状态后,就引入了一致性问题。流式计算系统的一致性主要表现在对计算结果的正确性级别。通常分为3种:at-most-once、at-least-once、exactly-once。

2.1 at-most-once

at-most-once级别提供的保证是最弱的,甚至是事件可以丢失,或者可以认为是没有保障的。最多一次指的就是事件被用于计算是最多一次的,计算系统发生故障或存储丢失后完全不用考虑。

2.2 at-least-once

at-least-once级别提供稍强一些的保证。在故障发生时可以达到事件不丢失,至少被纳入计算流程处理一次。但计算系统是不提供不超过一次的计算保证的。这在关键系统中需要外部应用通过幂等性等机制来补充更强的保证,但无疑会引起复杂性的增加。相对于at-most-once,这可以算是比较大的进步了,毕竟在外部系统配合下实现exactly-once变得可行,只是复杂性增加了而已。

2.3 exactly-once

exactly-once级别提供最好的保证。在故障发生时仍能做到事件仅被处理一次,保证了计算结果的正确性。而Flink就是提供exactly-once一致性级别计算引擎。另外,Storm、Sparking Streaming也能够提供exactly-once一致性级别的保证,但是付出了性能方面的代价。这在Flink出现前,对于性能要求严苛的环境,要么通过复杂的缓存/计算架构来解决,要么在性能和一致性级别上做出牺牲。

3 Flink如何实现exactly-once

3.1 checkpoint

Flink的checkpoint设计可谓神来之笔。在事件定义清晰的情况下,引入ckpt事件,结合ckpt算子,在最细粒度进行状态的快照,实现了exactly-once。

同时,通过ckpt事件的调度,故障阈值的调优,还可以在快照灵敏度上、故障发现及时性方面做更细致的调优。插入ckpt事件的数据流如下所示。

[ Event, Event, ckpt, Event, ..., Event, ckpt, Event, ..., Event, ckpt, Event, ... ]

而在消费ckpt时,由特殊的算子进行快照即可。

3.2 故障确认

Flink通过ckpt进行状态快照,但有时临时的存储不可靠并不影响计算结果的正确性。Flink通过多次连续的状态快照失败来确认故障发生。

3.3 故障恢复

故障发生后,集群将调度新的可用资源进行计算任务的执行。这时最后一次ckpt触发的成功快照将会被用于新认为的定位。以及哪些事件需要反演重播。这将需要Source进行配合完成。同时,如果事件基于ProcessingTime/IngestTime来作为时间基准,对计算结果的正确性也存在影响。

3.4 savepoint

Flink除了自动插入ckpt特殊事件外,还会开放手动插入svpt的接口,使得外界可以对计算进行暂停/恢复控制。这仍然能够提供计算的exactly-once一致性保证。

savepoint通常用于系统升级的处理,在具备反演特性的EventTime时间基准下,整个计算任务将会变得可控、可升级,而且正确。

4 我们走到了哪里

本篇对Flink提供的可靠性及原理进行分析。

Flink对流式计算实现了exactly-once一致性级别保证。使用ckpt和svpt机制,实现了对计算任务的正确性和可控性。这些特性对于需要升级维护、关键场景的应用提供了很好的保证。

接下来将继续探讨Flink中的其他核心概念。