为了账号安全,请及时绑定邮箱和手机立即绑定

端到端exactly-once(翻译官方)

标签:
Spark

1 概述

在Flink1.4.0中,发布了一个叫做TwoPhaseCommitSinkFunction的特性,该逻辑抽取两阶段提交协议常规逻辑,使得可以构建端到端的exactly-once语义,需要Kafka0.11以上。 本文余下部分主要讲述:

  • 描述Flink的checkpoint机制如何保证只处理一次语义

  • 描述Flink如何通过两阶段提交协议来达到端到端只处理一次语义

  • 通过一个简单例子来描述如何使用TwoPhaseCommitSinkFunction来完成到文件的只处理一次语义

2 端到端只处理一次实现

当我们说只处理一次语义时,意味着每个记录只影响结果一次,即使在发现机器或者软件故障是,都不会出现丢失以及重复处理。

实现该语义需要以flink本身的checkpoint机制为基础,这里简要进行下总结,一个应用的checkpoint由如下快照信息组成:

  • 当前应用的状态

  • 输入流的位置

Flink定时生成checkpoint,同时将checkpoint写入到持久化系统中。在写入过程中是异步的,意味着Flink在这个阶段继续处理数据。

为了提供端到端只处理一次语义,外部系统必须要提供方法来与flink本身的checkpoints机制结合,一种常用的协调提交以及回滚的方式是两阶段提交协议,接下来将具体分析下内部实现逻辑来达到端到端只处理一次语义。

由于在kafka0.11以上提供了事务处理,所以使得flink可以提供该机制,当前支持所有支持事务的源,本例中使用从kafka读取数据然后集合再输出到kafka中,如下图。

webp

image

为了保证只处理一次,需要在一个事务中完成数据写入kafka中,这样才能在失败时进行回滚。

然而,在分布式系统中,存在多个并行运行的sink task,一个简单的提交或者回滚是不行的,因为需要所有模块都一起提高或者回滚才能保证结果一致性,flink中使用两阶段提交协议中的预提交(pre-commit)来实现该功能。

在checkpoint启动时是两阶段提交协议的预提交阶段,当checkpoint启动,flink的jobmanager会注入一个栏栅消息(用于分隔当次checkpoint以及下一次checkpoint)。

栏栅消息在各个操作中传输,对于每一个操作,它都会出发操作进行状态快照。

webp

image

data source存储了kafka的offsets,当其完成后,将栏栅消息传给下一个操作。该情况下每个操作都是存储内部状态,不需要进行额外的操作,本身的checkpoint机制就可以满足。

webp

image

当有外部一些操作时,在pre-commit时就需要外部来保证状态的存储。

webp

image

当在预提交阶段完成了所有操作的snapshot(栏栅消息从source传到了sink),这时候状态包括了完成的状态,接下来时两阶段的提交阶段,jobmanager会通知各个操作快照结束并进行提交,由于除sink是存在外部状态的,其他都是内部状态,故而只需要提交sink的事务。

webp

image

  • 通过上图可以看出在所有操作完成了预提交时,才会进行提交

  • 在预提交阶段只要有一个失败,则回滚到上一次完成的checkpont

  • 在提交阶段的成功与否由外部系统来保证

3 checkpoint

进行快照后包含如下内容:

  • 对于每一个并行的source,快照存储的是offset、position等信息

  • 对于每一个操作,有一个指针指向快照存储



作者:薛定谔的猫Plus
链接:https://www.jianshu.com/p/1c5e442ca545


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消