开发者学堂课程【开源 Flink 极速上手教程:Fault-tolerance in Flink】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/331/detail/3710
Fault-tolerance in Flink(二)
三、Flink 的容错机制
1.流计算容错的一致性保证
容错:容错即恢复出错前的状态。这里的“出错”包含多种可能的原因,比如由于网络问题导致的 worker 失联,意外导致的进程 crash,应用程序错误等等。
对于错误恢复,Flink 可以提供不同级别的一致性保证:
(1).Exactly once(严格一次)
每条 event 会且只会对 state 产生一次影响
注意:并非端对端的严格一次
(2).At least once(最少一次)
每条 event 会对 state 产生最少一次影响(存在重复处理)
(3).At most once(最少一次)
每条 event 会对 state 产生最多一次影响
注意:所有状态会在出错时丢失
2.端到端的 Exactly once
Exactiy once:作业结果总是正确的,但是可能产出多次端到端的 Exactiy once:作业结果正确的,但是可能产出多次端到端的 Exactly once:作业结果正确且只会被产出一次
Exactlyonce(& 爱它 least once)要求
-可重放的 source
端到端的 exactly 要求
-事务型的 sink,或者
-可以接受幂等的产出结果
什么是端到端?它的意思是作业的结果都是正确的,只会被处理一次,但是有可能产出多次。
实际上就是数据在处理完了之后,结果写到数据库中,但是由于故障要回归,但是机制如果不支持回归的话,那数据其实就已经写出去了。另一个数据端的结果就是不一样的,就是它的结果正确,而且只会被铲除。所以说它的条件也是不一样的,所以在对公司的要求,实际上是一个可重放的 SASER 的要求,除了和中方之外,还要求这种失误性。什么是失误性?就是 checkpoint 在提交之前,写入到这一刻的数据,对于客户端是不可见的,只有提交了之后才可见。
3.状态容错
Flink 的状态容错,很多产品都会要求在出错后仅处理一次,如何确保语义?
(1).简单场景的 exactly once 容错方式
该场景比较简单,首先触发本地状态,而且把 SE de oftende1 位置记录下来即可。把数据从南端的消息队列到 S 位置的时候,把它本地的状态 X 记录下来,而它的道外的时候,把它的水平白给记录下来。本地就是进场,非常简单。
(2).分布式场景的状态容错
分布式场景怎么确保状态容错?首先对多个拥有的状态,算是产生一个全局一致性的拍照。要有一个全局性的拍照,去对分布式的场景进行分析。更重要的是在不中断预算的前提下。这两个条件,就是产品两个算法的系统要求。
(3).Flink 分布式场景的状态容错
Flink作业括扑:有向无环+弱连通图
Flink 作业括扑,它比较特殊。它是一个有向无环,并且是一个弱连通图。当然这并不是说 Flink 作业不支持,但是目前看到的大部分的流作业,流作业都是无权无法支持的。在这种情况,有向无环的弱点,共同的这种作业。就可以采用裁剪传达。
剪裁传达就是只记录所有输入的 offset,还有 fans 的状态,然后依靠 reliable source,可以回归的 SAS。比如 Kaska 的消息队列,可以通过 APP 去读取它,从比较早的一个时间点开始重新读取。它增加了一个依赖条件,就是回归的 SAS,它可以不去存储任意的差。逻辑是 application 结合逻辑,被称为 allegations,比如萨摩或者是 min 或者 max 的数据表达。数据还可以改善,预算楼梯底下,输入多条消息,处理之后就只有一条。或者 China state 里面可能有多条,但是 Operators 里面就只有最终的一个 max 或者一个 min,所以它其实是可以节省非常大量的事件,但是它不是没有代价的,任何的系统设计里面都是有渠道的,它是依赖增加的一个依赖条件,就是 levels,然后它如何恢复?把数据源的位置重新设定,然后每一个分子都从检查点恢复状态。
4.Flink 的分布式快照方法-Checkpoint barrier
Flink 的分布式拍照的方法
首先,它会在它的元数据的 data 地带插入它的 barrier。它是一种特殊的不同于应用消息的特殊消息,在 Flink 里面被称为开放白端,不同差宽的白端,就把流切分成了段,每段儿里边就包含了开放的数据。
它如何启动,在 Flink 字段里面它有一个全局的考虑,它不像产品,它在任意一个进程都可以发起一个拍照,Flink里面有一个子集,它会把 barrier 的数据注入到每一个小数点。然后启动拍照。
然后当每一个节点抽到标准之后。Flink里面它不存储 China state,所以它只需要去存储一个本地的状态就好。逻辑中,就比参加的说法要简化很多。
那最终什么时候结束?就是每一个算子的每一个拼法,在做完了产品之后,都会像数据一样发送一个确认的消息,当所有的任务都已经被开发好并收到之后,拍照就结束了。
(1).快照流程示意图
从 checkpoint,把数据注入到 state。它会把它现在处理的分区的 offset 先记录下来,然后随着时间的流失,把 checkpoint 分发到它的下游。然后当 barrier 分别到达这两个 state 的时候,这两个 state 分别把它们的状态记录在 checkpoint 里面。里边虽然是同时发送,实际上在实际的产品当中,不一定在两个半月的事件,因为网络的负载的情况不一样,跟它等的的算计所在的结点的运算能力都是有关系的。最后,让网络的干扰达到它的影响范围。最终告诉它,就是 offset 把它们的状态也记录下来了,也就完成了快照。这是一个很简单的产品。
(2).复杂场景——多流输入
-一个算子有多个输入
-快照时需要暂停 operator 的数据处理?
Barrier 对齐
当其中的一条流的概率已经到达了之后,但是另一条边儿的另一个 barrier,它还在广告中还没有到达,那时候会把先到哪一条留。直接给它组合掉,但是时候在保证一个14000的情况下,会把它直接解决掉,然后等待那一条留在处理。知道另外一条留的 barrier 也到达了之后。会安抚到它之前的这条路,然后同时把数据发送到 emit。过程当中,实际上网站会把一条流的处理注册掉了主色调。在实际上产生了什么效果?就这条流会发生一个反应,Flink 为了降低可能性,它对数据有 buffer ,也是有些大小。实际的一个效果,Rich 对齐会导致反压。
那 emit 的那一方面,就是看业务能不能接受隐性的降低。换成一个 At-least-once,变成 At-least-once 之后,如果不在这些过程中,左侧也说到阻塞的管道会发生什么事情。图好像不太对,如果不对齐,就会发现通道不阻塞了,它的数据就流进来了。其实是属于一个拆分数据,但是被包含在当前这块,所以一旦发生故障回复之后,由于 barrier 会被回退,所以提前流入的数据,就相当于会有一个重复的过程,所以数据就不再是决定因素了。
通过异步快照尽量减少任务停顿
本地快照时将本地快照的状态上传到分布式里本地的快照是同步上传到系统里的。
快照触发 stare copy-on-write
元数据信息做了快照后,数据处理恢复。这时上传数据过程中。
假设恢复的应用程序逻辑改了数据,不同的状态存储后端是不同的。如果是 Flink 用copy-on-write,如果是 RoscksDB 在 stateful 对本地进行快照,生产 DFS 键。