热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

flink的mysql两阶段提交_flinkexactlyonce系列之两阶段提交实现分析

flinkexactly-once系列目录:一、[两阶段提交概述](http:mp.weixin.qq.coms?__bizMzU5MTc1NDUyOA&mid224

flink exactly-once系列目录:

一、[两阶段提交概述](http://mp.weixin.qq.com/s?__biz=MzU5MTc1NDUyOA==&mid=2247483818&idx=1&sn=8c7bf4d00e81d7635bfa26b78a78ebba&chksm=fe2b65e5c95cecf349d9819fe6c998359cb9a8695abbdf74e326adc0503c8f330a2d47182b63&scene=21#wechat_redirect)

二、两阶段提交实现分析

三、StreamingFileSink源码分析

四、事务性输出实现

五、最终一致性实现

在【[两阶段提交概述](http://mp.weixin.qq.com/s?__biz=MzU5MTc1NDUyOA==&mid=2247483818&idx=1&sn=8c7bf4d00e81d7635bfa26b78a78ebba&chksm=fe2b65e5c95cecf349d9819fe6c998359cb9a8695abbdf74e326adc0503c8f330a2d47182b63&scene=21#wechat_redirect)】中介绍了两阶段提交的基本思路以及如何根据checkpoint机制来实现两阶段提交思路,flink给出来两阶段提交抽象实现TwoPhaseCommitSinkFunction与具体实现FlinkKafkaProducer011。

一、TwoPhaseCommitSinkFunction

TwoPhaseCommitSinkFunction是一个抽象类,继承RichSinkFunction,实现CheckpointedFunction与CheckpointListener接口。抽象出了以下四个方法:

beginTransaction, 开启一个事务,获得一个句柄

preCommit,执行预提交

commit ,执行提交

abort,放弃一个事务

使用这四个方法然后结合checkpoint 过程提供的hook,来实现两阶段提交过程,看下其具体调用流程:

a. initializeState 状态初始化方法,只会被调用一次,第一件事情是用来恢复上次checkpoint完成预提交的事务与下一次checkpoint开始的事务,对于上次checkpoint完成预提交说明该checkpoint已经完成,那么执行commit操作,下一次checkpoint开始的事务说明该checkpoint,那么执行abort操作,第二件事情是开启一个新的事务,给新的checkpoint使用;

b. snapshotState 与checkpoint同步周期性执行的方法,首先执行preCommit对本次checkpoint事务执行预提交操作,并且开启一个新的事务提供给下一次checkpoint使用,然后将这两个事务句柄存放在state中进行容错,preCommit提交的事务就是在失败后重启需要commit的事务,而新开启的事务就是在失败后重启需要放弃的事务;

c. notifyCheckpointComplete checkpoint完成之后的回调方法,负责对预提交的事务执行commit操作。

在上面的流程中,任何一个步骤都有可能会失败,如果在预提交阶段失败,任务会失败重启回到最近一次的checkpoint成功状态,预提交的事务自然会因为事务超时而放弃;如果在预提交之后提交之前也就是完成checkpoint 但是还没触发notifyCheckpointComplete动作,这个这个过程中失败,那么就会从这次成功的checkpoint中恢复,会执行initializeState中的逻辑保证数据的一致性;如果在commit之后下次checkpoint之前失败,也就是在执行notifyCheckpointComplete之后失败,那么任务重启会继续提交之前已经提交过的事务,因此事务的提交需要保证重复提交不会影响数据的一致性。整个流程分析下来,除了需要保证事务重复提交保证数据的一致性外,还需要保证事务句柄能够被持久化容错,以便失败后重启恢复,接下来看下输出kafka 是如何保证数据一致性的。

二、FlinkKafkaProducer011

kafka从0.11版本开始提供了幂等与事务的特性,保证了数据的一致性,具体可以参考https://www.infoq.cn/article/kafka-analysis-part-8这篇文章,幂等通过producerId与SequenceNumber 来保证,但是幂等只能保证对单个分区操作的数据一致性,事务通过transactionId、producerId、epoch三个元素来保证,transactionId由客户端指定,producerId内部实现但是对用户透明、epoch表示对相同transactionId 不同producer的区分。FlinkKafkaProducer011继承TwoPhaseCommitSinkFunction抽象类,将kafka事务机制与checkpoint结合,如下图:

e0937af22aa2

image

kafka的事务机制基本流程是先开启一个事务,然后发送数据,最后提交,将开启事务过程放在initializeState与snapshotState中,发送数据放在invoke中,flush 将所有缓存数据刷新到kafka ,相当于预提交操作,在snapshotState中执行,commitTransaction 提交操作放在notifyCheckpointComplete中执行。上面任何一个流程都有可能出现异常导致任务失败,对于kafka事务提交机制也是使用两阶段提交的模式,根据上一篇的分析,那么可能出现的问题就是在第二阶段,可能会出现部分提交成功部分提交失败导致数据不一致,如果能获取之前提交失败kafka 的transactionId、producerId、epoch这三个元素那么就可以在任务重启继续提交之前失败的事务,在flink 正好可以使用状态将这个三个元素进行容错,使重启之后可恢复。 在FlinkKafkaProducer011中使用KafkaTransactionState对象作为事务的句柄,保存着transactionId、producerId、epoch容错元素与FlinkKafkaProducer对象,FlinkKafkaProducer是transient类型的,不需要进行持久化,通过t-p-e就可以确定一个FlinkKafkaProducer。

理解以上流程就很好理解代码实现了,下面看几个重要的方法:

1. 开始事务,获得一个新的事务句柄

e0937af22aa2

image.gif

2. 预提交,执行flush操作

e0937af22aa2

image.gif

3. 提交,执行commitTransaction操作

e0937af22aa2

image.gif

4. 出现异常,任务重启放弃事务

e0937af22aa2

image.gif

三、两阶段提交实现总结

1. 外部存储需要满足事务特性

2. 外部存储需提供事务句柄,可持久化、可重新提交

3. 由于这种两阶段提交模式与checkpoint绑定在一起,checkpoint是周期性的执行,那么checkpoint周期的长短则会影响下游数据的延时性,需要根据实际使用情况来调整。

e0937af22aa2

企业微信截图_552a5b2d-e64f-41e2-be6b-865f5dc7a6dd.png



推荐阅读
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
  • win10清理电脑垃圾 ... [详细]
  • 竟然可以检查微信是否被删了好友?(Android Accessibility 了解一下)
    前言最近在研究Android辅助服务,实现了这个小工具,也算是对最近学习的一个总结。原理通过Android无障碍辅助功能实现模拟点击 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
author-avatar
低調浮華
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有