干货:Flink+Kafka 0.11端到端精确一次处理语义实现

Flink消费kafka消息实战,2021必看-Java高级面试题总结 @param raw @return */ public static SingleMessage parse(String r 【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】 浏览器打开:qq.cn.hn/FTf 免费领取 aw){ SingleMessage singleMessage = null; if (raw != null) { singleMessage = JSONObject.parseObject(raw, SingleMessag.. 阅读详情

干货:Flink+Kafka 0.11端到端精确一次处理语义实现

2018年08月03日 00:00:00 Spark高级玩法 阅读数:1566

 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.youkuaiyun.com/rlnLo2pNEfx9c/article/details/81369878

640?wx_fmt=png

实时处理里消息的仅一次处理是大家关注的重点吧,前面浪尖分享过一篇对比spark streaming 和 flink的文章 <Spark Streaming VS Flink>,里面讲到了如何用spark streaming实现仅一次处理及flink是实现仅一次处理的。本文主要是想详细阐述一下flink结合kafka 0.11的仅一次处理语义。

本文是浪尖翻译整理,英文原文阅读,请点击阅读原文。

640?wx_fmt=png

 

2017年12月Apache Flink社区发布了1.4版本。该版本正式引入了一个里程碑式的功能:两阶段提交Sink,即TwoPhaseCommitSinkFunction。该SinkFunction提取并封装了两阶段提交协议中的公共逻辑,自此Flink搭配特定source和sink(特别是0.11版本Kafka)搭建精确一次处理语义( exactly-once semantics)应用成为了可能。作为一个抽象类TwoPhaseCommitSinkFunction提供了一个抽象层供用户自行实现特定方法来支持 exactly-once semantics。

用户可以阅读Java文档来学习如何使用TwoPhaseCommitSinkFunction,或者参考Flink官网文档来了解FlinkKafkaProducer011是如何支持 exactly-once semantics的,因为后者正是基于TwoPhaseCommitSinkFunction实现的。

本文将深入讨论一下Flink 1.4这个新特性以及其背后的设计思想。在本文中我们将:

1. 描述Flink应用中的checkpoint如何帮助确保exactly-once semantics

2. 展示Flink如何通过两阶段提交协议与source和sink交互以实现端到端的  exactly-once semantics交付保障

3. 给出一个使用TwoPhaseCommitSinkFunction实现 exactly-once semantics的文件Sink实例

1640?wx_fmt=pngFlink应用的仅一次处理

 

当谈及仅一次处理时,我们真正想表达的是每条输入消息只会影响最终结果一次!【译者:影响应用状态一次,而非被处理一次】即使出现机器故障或软件崩溃,Flink也要保证不会有数据被重复处理或压根就没有被处理从而影响状态。长久以来Flink一直宣称支持 exactly-once semantics是指在一个Flink应用内部。在过去的几年间,Flink开发出了checkpointing机制,而它则是提供这种应用内仅一次处理的基石。

在继续之前我们简要总结一下checkpointing算法,这对于我们了解本文内容至关重要。简单来说,一个Flink checkpoint是一个一致性快照,它包含:

1. 应用的当前状态

2. 消费的输入流位置

Flink会定期地产生checkpoint并且把这些checkpoint写入到一个持久化存储上,比如S3或HDFS。这个写入过程是异步的,这就意味着Flink即使在checkpointing过程中也是不断处理输入数据的。

如果出现机器或软件故障,Flink应用重启后会从最新成功完成的checkpoint中恢复——重置应用状态并回滚状态到checkpoint中输入流的正确位置,之后再开始执行数据处理,就好像该故障或崩溃从未发生过一般。

在Flink 1.4版本之前,仅一次处理只限于Flink应用内。Flink处理完数据后需要将结果发送到外部系统,这个过程中Flink并不保证仅一次处理。但是Flink应用通常都需要接入很多下游子系统,而开发人员很希望能在多个系统上维持仅一次处理语义,即维持端到端的仅一次处理语义。

为了提供端到端的仅一次处理语义,仅一次处理语义必须也要应用于Flink写入数据的外部系统——故这些外部系统必须提供一种手段允许提交或回滚这些写入操作,同时还要保证与Flink checkpoint能够协调使用。

在分布式系统中协调提交和回滚的一个常见方法就是使用两阶段提交协议。下一章节中我们将讨论下Flink的TwoPhaseCommitSinkFunction是如何利用两阶段提交协议来实现exactly-once semantics的。

2640?wx_fmt=pngFlink实现仅一次语义的应用

 

下面将给出一个实例来帮助了解两阶段提交协议以及Flink如何使用它来实现仅一次处理语义。该实例从Kafka中读取数据,经处理之后再写回到Kafka。Kafka是非常受欢迎的消息队列,而Kafka 0.11.0.0版本正式发布了对于事务的支持——这是与Kafka交互的Flink应用要实现端到端仅一次语义的必要条件。

当然,Flink支持这种仅一次处理语义并不只是限于与Kafka的结合,可以使用任何source/sink,只要它们提供了必要的协调机制。举个例子,Pravega是Dell/EMC的一个开源流式存储系统,Flink搭配它也可以实现端到端的exactly-once semantics。

640?wx_fmt=png

本例中的Flink应用包含以下组件,如上图所示:

1. 一个source,从Kafka中读取数据(即KafkaConsumer)

2. 一个时间窗口化的聚会操作

3. 一个sink,将结果写回到Kafka(即KafkaProducer)

若要sink支持 exactly-once semantics,它必须以事务的方式写数据到Kafka,这样当提交事务时两次checkpoint间的所有写入操作当作为一个事务被提交。这确保了出现故障或崩溃时这些写入操作能够被回滚。

当然了,在一个分布式且含有多个并发执行sink的应用中,仅仅执行单次提交或回滚是不够的,因为所有组件都必须对这些提交或回滚达成共识,这样才能保证得到一个一致性的结果。Flink使用两阶段提交协议以及预提交(pre-commit)阶段来解决这个问题。

Flink checkpointing开始时便进入到pre-commit阶段。具体来说,一旦checkpoint开始,Flink的JobManager向输入流中写入一个checkpoint barrier将流中所有消息分割成属于本次checkpoint的消息以及属于下次checkpoint的。barrier也会在操作算子间流转。对于每个operator来说,该barrier会触发operator状态后端为该operator状态打快照。

640?wx_fmt=png

众所周知,flink kafka source保存Kafka消费offset,一旦完成位移保存,它会将checkpoint barrier传给下一个operator。

这个方法对于opeartor只有内部状态的场景是可行的。所谓的内部状态就是完全由Flink状态保存并管理的——本例中的第二个opeartor:时间窗口上保存的求和数据就是这样的例子。当只有内部状态时,pre-commit阶段无需执行额外的操作,仅仅是写入一些已定义的状态变量即可。当chckpoint成功时Flink负责提交这些写入,否则就终止取消掉它们。

640?wx_fmt=png

当时,一旦operator包含外部状态,事情就不一样了。我们不能像处理内部状态一样处理这些外部状态。因为外部状态通常都涉及到与外部系统的交互。如果是这样的话,外部系统必须要支持可与两阶段提交协议捆绑使用的事务才能确保实现整体的exactly-once semantics。

显然本例中的data sink是有外部状态的,因为它需要写入数据到Kafka。此时的pre-commit阶段下data sink在保存状态到状态存储的同时还必须预提交它的外部事务,如下图所示:

 640?wx_fmt=png 

当checkpoint barrier在所有operator都传递了一遍且对应的快照也都成功完成之后,pre-commit阶段才算完成。该过程中所有创建的快照都被视为是checkpoint的一部分。其实,checkpoint就是整个应用的全局状态,当然也包含pre-commit阶段提交的外部状态。当出现崩溃时,我们可以回滚状态到最新已成功完成快照时的时间点。

下一步就是通知所有的operator,告诉它们checkpoint已成功完成。这便是两阶段提交协议的第二个阶段:commit阶段。该阶段中JobManager会为应用中每个operator发起checkpoint已完成的回调逻辑。

本例中的data source和窗口操作无外部状态,因此在该阶段,这两个opeartor无需执行任何逻辑,但是data sink是有外部状态的,因此此时我们必须提交外部事务,如下图所示:

640?wx_fmt=png

汇总以上所有信息,总结一下:

1. 一旦所有operator完成各自的pre-commit,它们会发起一个commit操作

2. 倘若有一个pre-commit失败,所有其他的pre-commit必须被终止,并且Flink会回滚到最近成功完成decheckpoint

3. 一旦pre-commit完成,必须要确保commit也要成功——operator和外部系统都需要对此进行保证。倘若commit失败(比如网络故障等),Flink应用就会崩溃,然后根据用户重启策略执行重启逻辑,之后再次重试commit。这个过程至关重要,因为倘若commit无法顺利执行,就可能出现数据丢失的情况

因此,所有opeartor必须对checkpoint最终结果达成共识:即所有operator都必须认定数据提交要么成功执行,要么被终止然后回滚。

3640?wx_fmt=pngFlink中实现两阶段提交

 

这种operator的管理有些复杂,这也是为什么Flink提取了公共逻辑并封装进TwoPhaseCommitSinkFunction抽象类的原因。

下面讨论一下如何扩展TwoPhaseCommitSinkFunction类来实现一个简单的基于文件的sink。若要实现支持exactly-once semantics的文件sink,我们需要实现以下4个方法:

1. beginTransaction:开启一个事务,在临时目录下创建一个临时文件,之后,写入数据到该文件中

2. preCommit:在pre-commit阶段,flush缓存数据块到磁盘,然后关闭该文件,确保再不写入新数据到该文件。同时开启一个新事务执行属于下一个checkpoint的写入操作
3. commit:在commit阶段,我们以原子性的方式将上一阶段的文件写入真正的文件目录下。注意:这会增加输出数据可见性的延时。通俗说就是用户想要看到最终数据需要等会,不是实时的。
4. abort:一旦终止事务,我们离自己删除临时文件

当出现崩溃时,Flink会恢复最新已完成快照中应用状态。需要注意的是在某些极偶然的场景下,pre-commit阶段已成功完成而commit尚未开始(也就是operator尚未来得及被告知要开启commit),此时倘若发生崩溃Flink会将opeartor状态恢复到已完成pre-commit但尚未commit的状态。

在一个checkpoint状态中,对于已完成pre-commit的事务状态,我们必须保存足够多的信息,这样才能确保在重启后要么重新发起commit亦或是终止掉事务。本例中这部分信息就是临时文件所在的路径以及目标目录。

TwoPhaseCommitSinkFunction考虑了这种场景,因此当应用从checkpoint恢复之后TwoPhaseCommitSinkFunction总是会发起一个抢占式的commit。这种commit必须是幂等性的,虽然大部分情况下这都不是问题。本例中对应的这种场景就是:临时文件不在临时目录下,而是已经被移动到目标目录下。

4640?wx_fmt=png总结

 

本文的一些关键要点:

  1. Flinkcheckpointing机制是实现两阶段提交协议以及提供仅一次语义的基石

  2. 与其他系统持久化传输中的数据不同,Flink不需要将计算的每个阶段写入到磁盘中

  3. Flink新的TwoPhaseCommitSinkFunction封装两阶段提交协议的公共逻辑使之搭配支持事务的外部系统来共同构建仅一次语义应用成为可能

  4. 自1.4版本起,Flink + Pravega和Kafka 0.11 producer开始支持仅一次语义

  5. Flink Kafka 0.11 producer基于TwoPhaseCommitSinkFunction实现,比起至少一次语义的producer而言开销并未显著增加

推荐阅读:

Spark的PIDController源码赏析及backpressure详解

案例说明flink的udf

30分钟掌握沧湖一体化:flink+hudi(干货,建议收藏)_flink hudi sink Hudi存储层由三个不同的部分组成–它以时间轴的形式维护了在数据集上执行的所有操作的元数据,该时间轴允许将数据集的即时视图存储在基本路径的元数据目录下。时间轴上的操作类型包括。 阅读详情

相关推荐

30分钟掌握沧湖一体化:flink+hudi(干货,建议收藏)_flink hudi sink(1)

Hudi解决了以下限制。

2401_87204857的博客 631

flink-kafka-connector之FlinkKafkaConsumer011解析

目录flink kafka connector 调用关系     在使用flink kafka connector的时候,一般都直接像下面这样直接拷贝模板就拿来用了: Properties properties = new Properties(); properties.setProperty("bootstrap.servers", "localhost:9092"); properties.setProperty("group.id", "test"); env

CarbonDioxide12138的博客 7599

Vivado 2023.1及更早版本永久License全功能解锁:HLS、System Generator等IP核使用详解

本文深入解析Vivado 2023.1及更早版本的全功能许可证,详细指导如何解锁HLS、System Generator等高级IP核。通过许可证类型对比、功能验证方法和实战应用指南,帮助FPGA开发者充分利用Vivado工具套件,提升复杂系统设计和算法加速的效率。

weixin_31286719的博客 385

Flink源码解析 之 FlinkKafkaProducer011

1.构造方法 1.1 代码 public FlinkKafkaProducer011( String brokerList, String topicId, SerializationSchema<IN> serializationSchema); public FlinkKafkaProducer01...

qq_21020361的博客 4523

【数学模型】灰色关联分析

数学模型-灰色关联分析

suic009的博客 1万+

Windows下飞桨PaddlePaddle 2.6.1 GPU版环境搭建全攻略(含CUDA 11.7配置避坑指南)

本文详细介绍了在Windows系统下搭建飞桨PaddlePaddle 2.6.1 GPU版环境的完整流程,特别针对CUDA 11.7和cuDNN的安装提供了避坑指南。从Anaconda环境配置、CUDA Toolkit安装到飞桨GPU版的验证,手把手帮助开发者高效完成深度学习环境搭建,解决常见问题并优化性能。

x8y9z0的博客 1096

FLINK Producer数据写入到kafka 方法一

package kafkaproducer; import com.alibaba.fastjson.JSON; import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.environment.StreamExec.

80后大叔爱学习 3010

别再手动算K值了!ZEMAX中两种锥透镜建模方法详解(标准面 vs. 轴锥面)

本文详细解析了ZEMAX中锥透镜的两种建模方法:标准面与轴锥面。通过对比两者的精度、计算效率和适用场景,帮助工程师在激光整形、光束匀化等应用中做出最优选择,并提供了参数设置和异常排查的实用技巧。

weixin_42548874的博客 324

kafka作为flink输入源及输出源

flink的代码如下:(主要是接收kafka来的数据,然后做一些转换后,输出到kafka) import java.util.Properties import org.apache.flink.api.common.serialization.SimpleStringSchema import org.apache.flink.streaming.api.functions.source....

程序媛媛 1195

YOLOv8 架构改造实战:添加 P2 小目标检测头与 P6 超大目标检测头

上采样是指将特征图的空间尺寸变大(例如从 20×20 → 80×80),用来提升图像的分辨率。常见于解码器结构或特征融合中。下采样是指将特征图的空间尺寸缩小(例如从 256×256 → 128×128),通常用于减少计算量、提取更高级语义特征。操作目的方法尺寸变化上采样放大特征图插值算法变大(如2×)下采样压缩特征图、提取语义stride卷积等变小(如1/2)

FJN110的博客 575

【Linux命令大全】006.网络通讯之write命令(实操篇)

Linux write命令摘要 write是Linux系统中用于用户间实时通讯的命令工具,允许向其他登录用户的终端发送消息。主要功能包括: 基本使用:通过write username向指定用户发送消息,Ctrl+D结束输入 终端指定:当用户登录多个终端时,可用write username tty指定目标终端 实用技巧: 使用who查看在线用户 通过管道发送单行消息:echo "内容" | write user 支持多行消息发送和简单聊天会话。

yuhuasheng1997的博客 217

flink checkpoint 恢复_干货:Flink+Kafka 0.11端到端精确一次处理语义实现

2017年12月Apache Flink社区发布了1.4版本。该版本正式引入了一个里程碑式的功能:两阶段提交Sink,即TwoPhaseCommitSinkFunction。该SinkFunction提取并封装了两阶段提交协议中的公共逻辑,自此Flink搭配特定source和sink(特别是0.11版本Kafka)搭建精确一次处理语义(exactly-once semantics)应用...

weixin_31192609的博客 724

基于MATLAB的脑功能网络工具箱:BCT与FCLab

脑功能网络分析是神经科学领域的一个重要研究方向,它通过分析大脑中神经元之间的连接模式和信息传递方式,揭示脑网络的结构和功能。在这个领域,MATLAB是一个广泛使用的工具,提供了丰富的函数和工具箱来进行脑功能网络的分析和可视化。这些工具箱提供了丰富的函数和工具,使得脑功能网络的计算和分析变得更加简单和高效。在上述示例代码中,我们首先导入BCT工具箱,并构建一个邻接矩阵来表示脑网络的连接关系。在上述示例代码中,我们首先导入FCLab工具箱,并导入脑功能数据。函数对数据进行预处理,如去除噪声、降采样等操作。

web_bug407的博客 2611

大数据-112 Flink DataStream API :数据源、转换与输出 文件、Socket 到 Kafka 的完整流程

DataSource、Transformation 和 Sink。DataSource 提供多样化的数据输入方式,包括文件系统、消息队列、数据库及自定义数据源;Transformation 是计算的核心环节,支持 Map、FlatMap、Filter、KeyBy、Window 等操作,并能以链式调用构建完整的数据流处理管道;Sink 负责结果输出,可将数据写入消息系统、数据库或文件系统,并支持自定义实现。除了 addSource,Flink 还提供了便捷的方法如 fromCollection、readTex

谢谢你的喜欢 我们一起无限进步 6957

[ 虚拟专用网 ] IPsce 虚拟局域网(安全的IP协议的虚拟专用网)详解(二) --- 安全联盟SA

???? 博主介绍 ????‍???? 博主介绍:大家好,我是_PowerShell,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 ????点赞➕评论➕收藏 == 养成习惯(一键三连)???? ????欢迎关注????一起学习????一起讨论⭐️一起进步????文末有彩蛋 ????作者水平有限,欢迎各位大佬指点,相互学习进步! 目录 ???? 博主介绍 一、什么是安全联盟 二、协商参数两种方式:(手动、IKE) 1. 手动 2.

qq_51577576的博客 2802

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Flink & Iceberg 在去哪儿的实时数仓实践

摘要:‍‍‍‍‍‍‍‍本文介绍去哪儿数据平台在使用 Flink + Iceberg 0.11 的一些实践。‍‍‍‍‍‍‍‍内容包括:背景及痛点Iceberg 架构痛点一:Kafka 数据丢...

过往记忆大数据 766

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

干货 | Spark Streaming 和 Flink 详细对比

https://mp.weixin.qq.com/s/Fb1cW0oN7xYeb1oI2ixtgQ 以下文章来源于美图数据技术团队,作者浪尖 美图数据技术团队 美图拥有海量的用户数据,如何将美图的数据最大化的利用在各个场景,更大范围的发挥美图在数据上的优势,并挖掘数据无限的价值是我们的使命。我们会在这里推送技术干货文章、技术活动的通知、团队的介绍以及招聘信息。欢迎关注~~ 本文由美图数据技术团队授权转载,原文 https://mp.weixin.qq.com/s/jllAegJMY...

hellojoy的博客 730

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Flink + Iceberg 在去哪儿的实时数仓实践

摘要:本文介绍去哪儿数据平台在使用 Flink + Iceberg 0.11 的一些实践。内容包括:背景及痛点Iceberg 架构痛点一:Kafka 数据丢失痛点二:近实时 Hive 压力...

Ververica的博客 348

推荐两个不错的flink项目

题外话,感觉文章可以就点击一些广告呗,谢谢。最近flink真是风生水起,但是浪院长看来这不过是阿里错过了创造spark影响力之后,想要在flink领域创建绝对的影响力。但...

大数据星球-浪尖 1万+

Flink在与AI集成的路上再次“遥遥领先” - Flink Agents

在AI技术快速渗透企业场景的当下,如何让AI Agent稳定处理实时海量数据、实现高容错与低时延运行,成为企业数字化转型的关键需求。Apache Flink Agents作为Apache Flink的全新子项目,恰好填补了这一空白,将流处理能力与AI Agent功能深度融合,为企业级Agent应用提供了全新解决方案。以下从项目概览、核心价值、技术特性包括Java/Python/SQL code示例、版本与roadmap等方面,梳理其核心要点。

智海观潮的博客 1442
上一篇: MongoDB存储引擎选择
下一篇: storm 批处理(窗口)
王树民
博客等级 码龄10年 912粉丝 560原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值