热门标签 | 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



推荐阅读
  • 从0到1搭建大数据平台
    从0到1搭建大数据平台 ... [详细]
  • MySQL 5.7 学习指南:SQLyog 中的主键、列属性和数据类型
    本文介绍了 MySQL 5.7 中主键(Primary Key)和自增(Auto-Increment)的概念,以及如何在 SQLyog 中设置这些属性。同时,还探讨了数据类型的分类和选择,以及列属性的设置方法。 ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 在Java编程中,初始化List集合有多种高效的方法。本文介绍了六种常见的技术,包括使用常规方式、Arrays.asList、Collections.addAll、Java 8的Stream API、双重大括号初始化以及使用List.of。每种方法都有其特定的应用场景和优缺点,开发者可以根据实际需求选择最合适的方式。例如,常规方式通过直接创建ArrayList对象并逐个添加元素,适用于需要动态修改列表的情况;而List.of则提供了一种简洁的不可变列表初始化方式,适合于固定数据集的场景。 ... [详细]
  • 本文探讨了在PHP中实现MySQL分页查询功能的优化方法与实际应用。通过详细分析分页查询的常见问题,提出了多种优化策略,包括使用索引、减少查询字段、合理设置缓存等。文章还提供了一个具体的示例,展示了如何通过优化模型加载和分页参数设置,显著提升查询性能和用户体验。 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 深入探索HTTP协议的学习与实践
    在初次访问某个网站时,由于本地没有缓存,服务器会返回一个200状态码的响应,并在响应头中设置Etag和Last-Modified等缓存控制字段。这些字段用于后续请求时验证资源是否已更新,从而提高页面加载速度和减少带宽消耗。本文将深入探讨HTTP缓存机制及其在实际应用中的优化策略,帮助读者更好地理解和运用HTTP协议。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 解决问题:1、批量读取点云las数据2、点云数据读与写出3、csf滤波分类参考:https:github.comsuyunzzzCSF论文题目ÿ ... [详细]
  • 2.2 组件间父子通信机制详解
    2.2 组件间父子通信机制详解 ... [详细]
  • 在本文中,我们将详细介绍如何构建一个用于自动回复消息的XML类。当微信服务器接收到用户消息时,该类将生成相应的自动回复消息。以下是具体的代码实现:```phpclass We_Xml { // 代码内容}```通过这个类,开发者可以轻松地处理各种消息类型,并实现高效的自动回复功能。我们将深入探讨类的各个方法和属性,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文探讨了如何利用Java代码获取当前本地操作系统中正在运行的进程列表及其详细信息。通过引入必要的包和类,开发者可以轻松地实现这一功能,为系统监控和管理提供有力支持。示例代码展示了具体实现方法,适用于需要了解系统进程状态的开发人员。 ... [详细]
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社区 版权所有