Flink实战(11)-Exactly-Once语义之两阶段提交

0 大纲

[Apache Flink]2017年12月发布的1.4.0版本开始,为流计算引入里程碑特性:TwoPhaseCommitSinkFunction。它提取了两阶段提交协议的通用逻辑,使得通过Flink来构建端到端的Exactly-Once程序成为可能。同时支持:

  • 数据源(source)
  • 和输出端(sink)

包括Apache Kafka 0.11及更高版本。它提供抽象层,用户只需实现少数方法就能实现端到端Exactly-Once语义。

新功能及Flink实现逻辑:

  • 描述Flink checkpoint机制如何保证Flink程序结果的Exactly-Once的
  • 显示Flink如何通过两阶段提交协议与数据源和数据输出端交互,以提供端到端的Exactly-Once保证
  • 通过一个简单的示例,了解如何使用TwoPhaseCommitSinkFunction实现Exactly-Once的文件输出

1 Flink应用中的Exactly-Once语义

Exactly-Once,指每个输入的事件只影响最终结果一次。即使机器或软件故障,既没有重复数据,也不会丢数据。

Flink很久就提供Exactly-Once,checkpoint机制是Flink有能力提供Exactly-Once语义的核心。

一次checkpoint是以下内容的一致性快照:

  • 应用程序的当前状态
  • 输入流的位置

Flink可配置一个固定时间点,定期产生checkpoint,将checkpoint的数据写入持久存储系统,如S3或HDFS。将checkpoint数据写入持久存储是异步,即Flink应用程序在checkpoint过程中可以继续处理数据。

如果发生机器或软件故障,重新启动后,Flink应用程序将从最新的checkpoint点恢复处理; Flink会恢复应用程序状态,将输入流回滚到上次checkpoint保存的位置,然后重新开始运行。这意味着Flink可以像从未发生过故障一样计算结果。

Flink 1.4.0前,Exactly-Once语义仅限Flink应用程序内部,没有扩展到Flink数据处理完后发送的大多数外部系统。Flink应用程序与各种数据输出端进行交互,开发人员自己维护组件上下文保证Exactly-Once语义。

为提供端到端的Exactly-Once语义 – 即除了Flink应用程序内部,Flink写入的外部系统也需要能满足Exactly-Once语义 – 这些外部系统必须提供提交或回滚的方法,然后通过Flink的checkpoint机制协调。

分布式系统中,协调提交和回滚的常用方法是2pc协议。讨论Flink的TwoPhaseCommitSinkFunction如何利用2pc提供端到端的Exactly-Once语义。

2 Flink应用程序端到端的Exactly-Once语义

Kafka经常与Flink使用。Kafka 0.11版本添加事务支持。这意味着现在通过Flink读写Kafaka,并提供端到端的Exactly-Once语义有了必要支持。

Flink对端到端的Exactly-Once语义的支持不仅局限Kafka,可将它与任何一个提供必要的协调机制的源/输出端一起使用。如Pravega,来自DELL/EMC的开源流媒体存储系统,通过Flink的TwoPhaseCommitSinkFunction也能支持端到端的Exactly-Once语义。

image-20231124142310942

示例程序有:

  • 从Kafka读取的数据源(Flink内置的KafkaConsumer)
  • 窗口聚合
  • 将数据写回Kafka的数据输出端(Flink内置的KafkaProducer)

要使数据输出端提供Exactly-Once保证,须将所有数据通过一个事务提交给Kafka。提交捆绑了两个checkpoint之间的所有要写数据。这确保在故障时,能回滚写入的数据。但分布式系统中,通常有多个并发运行的写入任务,所有组件须在提交或回滚时“一致”才能确保一致结果。Flink使用2PC及预提交阶段解决这问题。

pre-commit

checkpoint开始时,即2PC的“预提交”阶段。当checkpoint开始时,Flink的JobManager会将checkpoint barrier(将数据流中的记录分为进入当前checkpoint与进入下一个checkpoint)注入数据流。

brarrier在operator之间传递。对每个operator,它触发operator的状态快照写入state backend。

数据源保存了消费Kafka的偏移量(offset),之后将checkpoint barrier传递给下一operator。

这种方式仅适用于operator具有『内部』状态。

内部状态

指Flink state backend保存和管理的。如第二个operator中window聚合算出来的sum值。当一个进程有它的内部状态时,除了在checkpoint前需将数据变更写入state backend,无需在pre-commit阶段执行其他操作。

Flink负责在checkpoint成功时正确提交这些写入或故障时中止这些写入。

image-20231124150402626

3 Flink应用启动pre-commit阶段

当进程具有『外部』状态,需额外处理。外部状态通常以写入外部系统(如Kafka)的形式出现。此时,为提供Exactly-Once保证,外部系统须【支持事务】,才能和两阶段提交协议集成。

示例数据需写入Kafka,因此数据输出端(Data Sink)有外部状态。此时,在预提交阶段:

  • 除了将其状态写入state backend
  • 数据输出端还必须预先提交其外部事务

当checkpoint barrier在所有operator都传递了一遍,并且触发的checkpoint回调成功完成时,预提交阶段结束。所有触发的状态快照都被视为该checkpoint的一部分。checkpoint是整个应用程序状态的快照,包括预先提交的外部状态。若故障,可回滚到上次成功完成快照的时间点。

下一步是通知所有operator,checkpoint已经成功了。这是2PC的提交阶段,JobManager为应用程序中的每个operator发出checkpoint已完成的回调。

数据源和 widnow operator没有外部状态,因此在提交阶段,这些operator不必执行任何操作。但是,数据输出端(Data Sink)拥有外部状态,此时应该提交外部事务。

总结

  • 一旦所有operator完成预提交,就提交一个commit。
  • 如果至少有一个预提交失败,则所有其他提交都将中止,我们将回滚到上一个成功完成的checkpoint。
  • 在预提交成功之后,提交的commit需要保证最终成功 – operator和外部系统都需要保障这点。如果commit失败(例如,由于间歇性网络问题),整个Flink应用程序将失败,应用程序将根据用户的重启策略重新启动,还会尝试再提交。这个过程至关重要,因为如果commit最终没有成功,将会导致数据丢失。

因此,我们可以确定所有operator都同意checkpoint的最终结果:所有operator都同意数据已提交,或提交被中止并回滚。

4 在Flink中实现两阶段提交Operator

完整的实现两阶段提交协议可能有点复杂,这就是为什么Flink将它的通用逻辑提取到抽象类TwoPhaseCommitSinkFunction中的原因。

接下来基于输出到文件的简单示例,说明如何使用TwoPhaseCommitSinkFunction。用户只需要实现四个函数,就能为数据输出端实现Exactly-Once语义:

  • beginTransaction – 在事务开始前,我们在目标文件系统的临时目录中创建一个临时文件。随后,我们可以在处理数据时将数据写入此文件。
  • preCommit – 在预提交阶段,我们刷新文件到存储,关闭文件,不再重新写入。我们还将为属于下一个checkpoint的任何后续文件写入启动一个新的事务。
  • commit – 在提交阶段,我们将预提交阶段的文件原子地移动到真正的目标目录。需要注意的是,这会增加输出数据可见性的延迟。
  • abort – 在中止阶段,我们删除临时文件。

我们知道,如果发生任何故障,Flink会将应用程序的状态恢复到最新的一次checkpoint点。一种极端的情况是,预提交成功了,但在这次commit的通知到达operator之前发生了故障。在这种情况下,Flink会将operator的状态恢复到已经预提交,但尚未真正提交的状态。

我们需要在预提交阶段保存足够多的信息到checkpoint状态中,以便在重启后能正确的中止或提交事务。在这个例子中,这些信息是临时文件和目标目录的路径。

TwoPhaseCommitSinkFunction已经把这种情况考虑在内了,并且在从checkpoint点恢复状态时,会优先发出一个commit。我们需要以幂等方式实现提交,一般来说,这并不难。在这个示例中,我们可以识别出这样的情况:临时文件不在临时目录中,但已经移动到目标目录了。

在TwoPhaseCommitSinkFunction中,还有一些其他边界情况也会考虑在内,请参考Flink文档了解更多信息。

FAQ

flink sink在如果过来一个checkpoint barrier,会去存储state,这个动作会和普通的write并行吗?还是串行?

在Flink的checkpoint机制中,当一个Checkpoint Barrier过来时,sink会触发对状态的snapshot,这个snapshot动作默认是和普通的write操作并行进行的。

具体来说:

  • Flink的checkpoint机制是通过在datastream中注入Checkpoint Barrier来实现的。

  • 当source接收到Checkpoint Barrier时,会将其传递给下游的transformation和sink。

  • 当sink接收到Checkpoint Barrier时,会启动一个新的线程来执行state snapshot(状态保存)。

  • 这个状态snapshot线程会从状态后端Snapshot State,并存储检查点。

  • 而sink的主线程在接收到Checkpoint Barrier时,会继续处理正常的write。

  • 这样,状态snapshot和正常的write操作就是并行进行的。

但是也可以通过Sink的配置来设置snapshot和write的执行策略,主要有两种模式:

  1. 并行模式(默认):snapshot和write同时进行

  2. 串行模式:snapshot完成后再进行write

综上,Flink sink在默认的并行checkpoint模式下,状态snapshot和普通的write操作是并行执行的。可以通过配置来改变其行为。这样可以根据实际需要进行平衡。

总结

  • Flink的checkpoint机制是支持两阶段提交协议并提供端到端的Exactly-Once语义的基础。
  • 这个方案的优点是: Flink不像其他一些系统那样,通过网络传输存储数据 – 不需要像大多数批处理程序那样将计算的每个阶段写入磁盘。
  • Flink的TwoPhaseCommitSinkFunction提取了两阶段提交协议的通用逻辑,基于此将Flink和支持事务的外部系统结合,构建端到端的Exactly-Once成为可能。
  • 从Flink 1.4.0开始,Pravega和Kafka 0.11 producer都提供了Exactly-Once语义;Kafka在0.11版本首次引入了事务,为在Flink程序中使用Kafka producer提供Exactly-Once语义提供了可能性。
  • Kafaka 0.11 producer的事务是在TwoPhaseCommitSinkFunction基础上实现的,和at-least-once producer相比只增加了非常低的开销。

    本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/188515.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ElasticSearch查询语法及深度分页问题

一、ES高级查询Query DSL ES中提供了一种强大的检索数据方式,这种检索方式称之为Query DSL(Domain Specified Language 领域专用语言) , Query DSL是利用Rest API传递JSON格式的请求体(RequestBody)数据与ES进行交互,这种方式的丰富查询语法…

html实现我的故乡,城市介绍网站(附源码)

文章目录 1. 我生活的城市北京(网站)1.1 首页1.2 关于北京1.3 北京文化1.4 加入北京1.5 北京景点1.6 北京美食1.7 联系我们 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43…

【Linux】匿名管道与命名管道,进程池的简易实现

文章目录 前言一、匿名管道1.管道原理2.管道的四种情况3.管道的特点 二、命名管道1. 特点2.创建命名管道1.在命令行上2.在程序中 3.一个程序执行打开管道并不会真正打卡 三、进程池简易实现1.makefile2.Task.hpp3.ProcessPool.cpp 前言 一、匿名管道 #include <unistd.h&g…

链表?细!详细知识点总结!

链表 定义&#xff1a;链表是一种递归的数据结构&#xff0c;它或者为空&#xff08;null)&#xff0c;或者是指向一个结点&#xff08;node&#xff09;的引用&#xff0c;该结点含有一个泛型的元素和一个指向另一条链表的引用。 ​ 其实链表就是有序的列表&#xff0c;它在内…

批量按顺序1、2、3...重命名所有文件夹里的文件

最新&#xff1a; 最快方法&#xff1a;先用这个教程http://文件重命名1,2......nhttps://jingyan.baidu.com/article/495ba841281b7079b20ede2c.html再用这个教程去空格&#xff1a;利用批处理去掉文件名中的空格-百度经验 (baidu.com) 以下为原回答 注意文件名有空格会失败…

Javaweb之Vue组件库Element的详细解析

4 Vue组件库Element 4.1 Element介绍 不知道同学们还否记得我们之前讲解的前端开发模式MVVM&#xff0c;我们之前学习的vue是侧重于VM开发的&#xff0c;主要用于数据绑定到视图的&#xff0c;那么接下来我们学习的ElementUI就是一款侧重于V开发的前端框架&#xff0c;主要用…

深信服实验学习笔记——nmap常用命令

文章目录 1. 主机存活探测2. 常见端口扫描、服务版本探测、服务器版本识别3. 全端口&#xff08;TCP/UDP&#xff09;扫描4. 最详细的端口扫描5. 三种TCP扫描方式 1. 主机存活探测 nmap -sP <靶机IP>-sP代表 2. 常见端口扫描、服务版本探测、服务器版本识别 推荐加上-v参…

C++初阶(十二)string的模拟实现

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、string类的模拟实现1、构造、拷贝构造、赋值运算符重载以及析构函数2、迭代器类3、增删查…

Nacos安装使用

Nacos安装使用 官方下载地址: https://github.com/alibaba/nacos/releases 官方文档地址: https://nacos.io/zh-cn/docs/quick-start.html Nacos介绍 Nacos是阿里巴巴开源的一款支持服务注册与发现&#xff0c;配置管理以及微服务管理的组件。用来取代以前常用的注册中心&a…

史上最全前端知识点+高频面试题合集,十二大专题,命中率高达95%

前言&#xff1a; 下面分享一些关于阿里&#xff0c;美团&#xff0c;深信服等公司的面经&#xff0c;供大家参考一下。大家也可以去收集一些其他的面试题&#xff0c;可以通过面试题来看看自己有哪里不足。也可以了解自己想去的公司会问什么问题&#xff0c;进行有针对的复习。…

基于springboot网上超市管理系统

基于springboot网上超市管理系统 摘要 随着互联网的快速发展&#xff0c;电子商务行业迎来了蓬勃的发展&#xff0c;网上超市作为电子商务的一种形式&#xff0c;为消费者提供了便利的购物体验。本文基于Spring Boot框架&#xff0c;设计和实现了一个网上超市管理系统&#xff…

项目中如何配置数据可视化展现

在现今数据驱动的时代&#xff0c;可视化已逐渐成为数据分析的主要途径&#xff0c;可视化大屏的广泛使用便应运而生。很多公司及政务机构&#xff0c;常利用大屏的手段展现其实力或演示业务&#xff0c;可视化的效果能让观者更快速的理解结果并直观的看到数据展现。因此&#…

【Web】NewStarCtf Week2 个人复现

目录 ①游戏高手 ②include 0。0 ③ez_sql ④Unserialize&#xff1f; ⑤Upload again! ⑥ R!!C!!E!! ①游戏高手 经典前端js小游戏 检索与分数相关的变量 控制台直接修改分数拿到flag ②include 0。0 禁了base64和rot13 尝试过包含/var/log/apache/access.log,ph…

图论|知识图谱——详解自下而上构建知识图谱全过程

导读&#xff1a;知识图谱的构建技术主要有自顶向下和自底向上两种。其中自顶向下构建是指借助百科类网站等结构化数据源&#xff0c;从高质量数据中提取本体和模式信息&#xff0c;加入到知识库里。而自底向上构建&#xff0c;则是借助一定的技术手段&#xff0c;从公开采集的…

3.2 CPU的自动化

CPU的自动化 改造1-使用2进制导线改造2根据整体流程开始改造指令分析指令MOV_A的开关2进制表格手动时钟gif自动时钟gif 根据之前的CPU内部结构改造,制造一个cpu控制单元 改造一 之前的CPU全由手动开关自己控制,极度繁琐,而开关能跟二进制一一对应, 开:1, 关:0图1是之前的, …

Vue3的计算属性(computed)和监听器(watch)案例语法

一&#xff1a;前言 Vue3 是 Vue2 的一个升级版&#xff0c;随着 2023年12月31日起 Vue2 停止维护。这意味着 Vue3 将会为未来国内一段时间里&#xff0c;前端的开发主流。因此熟练的掌握好 Vue3 是前端开发程序员所不可避免的一门技术栈。而 Vue3 是 Vue2 的一个升级版&#x…

易错知识点(数学一)

一、反常积分判敛 1、构造使其极限等于一个大于0的常数 1&#xff09;前者通过&#xff1a;化等价无穷小 or 泰勒展开 2&#xff09;若存在p>1使得等式成立&#xff0c;则收敛 考察形式&#xff1a;1、已知收敛&#xff0c;求f(x)中的幂次取值范围 主要思想&#xff1a;比较…

linux嵌入式时区问题

目录 操作说明实验参考 最近有个针对时区的需求&#xff0c;研究了下。 查询网上的一些设置&#xff0c;发现基本都是系统中自带的一些文件&#xff0c;然后开机时解析&#xff0c;或者是有个修改的命令。 操作 但针对嵌入式常用到的 busybox 制作的最小系统&#xff0c;并没…

UI自动化(selenium+python)之元素定位的三种等待方式!

前言 在UI自动化过程中&#xff0c;常遇到元素未找到&#xff0c;代码报错的情况。这种情况下&#xff0c;需要用等待wait。 在selenium中可以用到三种等待方式即sleep,implicitly_wait,WebDriverWait 一、固定等待(sleep) 导入time模块&#xff0c;设定固定的等待时间 缺…

基于vue+element-plus+echarts编写动态绘图页面

我们都知道网页的echarts可以画图&#xff0c;但是很多情况下都需要编码实现绘图逻辑&#xff0c;如果有一个前端页面可以让我输入数据然后动态生成图表的话那么该多好&#xff0c;其实这个需求不难实现&#xff0c;先看效果。 整体页面分为左右两个部分&#xff0c;其中左边的…