Flink端到端一致性

2022-04-18 13:40:44 浏览数 (1)

流式计算中,端到端表示从外部读取数据、中间处理、数据输出外部三个处理环节。在理想状态即7*24任务不出错或者异常情况下,也就是每一步处理都正常,那么就能保证最终处理输出的数据正确,但是在实际的情况中,可能会出现网络、磁盘、脏数据、OOM等各种异常导致程序失败,也就是端到端任何一个处理环节都有可能失败,为了保证最终数据的正确性,需要提供一种机制保障在面对任何情况的情况下,任务仍然恢复到正确的状态,也就是本篇要说的端到端的一致性。

流式计算三种处理语义

At-Most-Once

At-Most-Once 表示至多处理一次,在端到端的整个处理流程中,每一个环节至多会被处理一次,通常发生在某一个处理环节在出现失败导致异常的情况下,下游节点是无法获取到该节点的处理数据的,因为失败的数据不会被重试或者是恢复,所以是至多一次

At-Least-Once

At-Least-Once 表示至少处理一次,可能由于中间由于某个环节异常(处理消息异常、提交offset异常等) 导致消息被重复消费重新进入整个处理流程中

Exactly-Once

Exactly-Once 表示恰好处理一次,在端到端的整个流程中,消息只会被正确处理一次。

有没有真正的Exactly-Once?

Exactly-Once的处理语义需要保证数据在流式处理中的每一个节点只会被正确处理一次,也就是既不能重复处理也不能有遗漏处理的数据,但是在实际的分布式处理中是无法保证每一个环节都能够不出异常,可能会由于程序本身异常或者是网络磁盘异常导致程序crash等, 导致数据在程序中被重复处理,因此是没有真正的Exactly-Once。而端到端的一致性是保证程序在异常情况下与没有产生异常情况下其最终处理的结果一样。

端到端一致性需要满足的三个条件

基本上在一切的事物处理方式中,我们都会考虑异常情况下的应对措施,晚自习停电了可以点蜡烛学习,没有米饭了可以吃面条,面条也没有了需要你抗饿等等。那么端到端的一致性保障机制同样也是基于异常情况的应对处理机制,先说结论,三个条件是:

  • 上游数据可重放
  • 中间状态保障
  • 幂等输出

流式计算是一个无边界的数据流处理过程,不断的从数据源出读取数据,不断的处理并且输出,对于消费到的上游数据,有可能刚刚获取到该数据、还未完成计算或者是还未输出到下游,程序就异常重启,重启之后需要能够再次获取到该未处理完成的数据,因此需要上游数据源端数据可重发;

状态即数据,可以是元数据也可以是任务处理的中间数据,状态处理可以分为有状态、无状态,无状态表示前后处理的数据之前没有任何关联,有状态表示当前处理的数据需要依赖上一次处理数据结果,例如计数、平均值等。在流计算中通常是有状态的计算,对于中间状态来说需要保证在异常恢复情况下仍然能够保证数据的正确性;

异常情况下,数据重放或者是重复处理,带来的结果就是输出端会重复输出,对于重复输出的方式就是使用幂等处理,无论重复操作多少次其结果都是一样的,将不确定的计算转换为确定的计算。

在Flink中如何实现端到端一致性

上游数据可重放-持久化的数据源

可重放数据表示需要可持久化的数据源,Flink对接上游数据源通常为Kafka、Metaq等持久化的消息队列,在任务重启时刻根据当前的消费位点offset重新获取数据。

状态保障-全局一致性快照

Flink容错机制的核心就是分布式的全局一致性状态快照即checkpoint,Flink任务会定时保存当前的任务状态,对于数据源端通常对应当前消费的offset,对于处理节点对应中间的处理中间数据,任务在恢复时默认会从最近一次成功的快照恢复,回到恢复点的全局一致性状态。

幂等输出

由于无法避免的重复消费与重复处理,在输出端需要做幂等处理,通常处理的方式是接收端MySql设置unique key、hbase的rowKey机制保证幂等。

特殊的2PC

2PC即两阶段提交,在上面提到的幂等机制需要下游存储本身支持幂等的处理,但是输出端如果是HDFS、Kafka,其没唯一键或者是去重键的概念,那么就无法使用幂等机制,因此就需要使用事务机制。

Flink两阶段提交依托于其Checkpoint机制,在发起checkpoint执行第一阶段提交,完成checkpoint回调时执行第二阶段提交,可以理解为将外部存储的数据纳入到了其内部的全局一致性状态中。

0 人点赞