Flink的状态一致性

news2024/11/24 17:35:36

一致性的划分

通常来说,状态一致性分为三个级别

  • at-most-once:至多一次,发生故障恢复后数据可能丢失
  • at-least-once:至少一次,发生故障恢复后数据可能多算,绝对不会少算
  • exactly-once:精确一次,发生故障恢复后数据不会丢失也不会多算

端到端的状态一致性

Flink 中使用的是一种轻量级快照机制——检查点(checkpoint)来保证 exactly-once 语义。但是我们的应用还包含了数据源和输出,每个组件都只是保证了自己的一致性,所以端到端级别的一致性取决于所有组件中一致性最弱的组件。

要满足端到端的状态一致性需要满足以下几点:

  • source:需要外部数据源可以重新设置数据的读取位置
  • 内部:通过checkpoint保证内部的一致性
  • sink:从故障恢复时,数据不会重复写入到外部系统

source端保证

         source端主要指的就是 Flink 读取的外部数据源。对于一些数据源来说,并不提供数据的缓
冲或是持久化保存,数据被消费之后就彻底不存在了。想要在故障恢复后不丢数据,外部数据源就必须拥有重放数据的能力。常见的做法就是对数据进行持久化保存,并且可以重设数据的读取位置。一个最经典的应用就是 Kafka。在 Flink的 Source 任务中将数据读取的偏移量保存为状态,这样就可以在故障恢复时从检查点中读取出来,对数据源重置偏移量,重新获取数据。这样就可以保证数据不丢。这是达到 exactly-once 的基本要求。

sink端保证

         想要实现 exactly-once 却存在很大的困难:数据有可能重复写入外部系统。 因为检查点保存之后,继续到来的数据也会一一处理,任务的状态也会更新,最终通过 Sink 任务将计算结果输出到外部系统;只是状态改变还没有存到下一个检查点中。这时如果 出现故障,这些数据都会重新来一遍,就计算了两次。我们知道对 Flink 内部状态来说,重复计算的动作是没有影响的,因为状态已经回滚,最终改变只会发生一次;但对于外部系统来说,已经写入的结果就是泼出去的水,已经无法收回了,再次执行写入就会把同一个数据写入两次。 所以这时,我们只保证了端到端的 at-least-once 语义。 为了实现端到端 exactly-once,我们还需要对外部存储系统、以及 Sink 连接器有额外的要 求。能够保证 exactly-once 一致性的写入方式有两种: 幂等写入和事务写入

幂等(idempotent)写入

        所谓“幂等”操作,就是说一个操作可以重复执行很多次,但只导致一次结果更改。也就是说,后面再重复执行就不会对结果起作用了。
        这相当于说,我们并没有真正解决数据重复计算、写入的问题;而是说,重复写入也没关 系,结果不会改变。所以这种方式主要的限制在于外部存储系统必须支持这样的幂等写入:比 如 Redis 中键值存储,或者关系型数据库(如 MySQL)中满足查询条件的更新操作。
        对于幂等写入,遇到故障进行恢复时,有可能会出现短暂的不一致。因为保存 点完成之后到发生故障之间的数据,其实已经写入了一遍,回滚的时候并不能消除它们。

事务(transactional)写入

         事务(transaction)是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所做的所有更改都会被撤消。事务写入的基本思想就是:用一个事务来进行数据向外部系统的写入,这个事务是与检查点绑定在一起的。当 Sink 任务 遇到 barrier 时,开始保存状态的同时就开启一个事务,接下来所有数据的写入都在这个事务中;待到当前检查点保存完毕时,将事务交,所有写入的数据就真正可用了。如果中间过程 出现故障,状态会回退到上一个检查点,而当前事务没有正常关闭(因为当前检查点没有保存 完),所以也会回滚,写入到外部的数据就被撤了。
具体来说,又有两种实现方式:预写日志(WAL)和两阶段提交(2PC)
(1)预写日志(write-ahead-log,WAL)
预写日志(WAL)就是一种非常简单的方式。具体步骤是:
①先把结果数据作为日志(log)状态保存起来
②进行检查点保存时,也会将这些结果数据一并做持久化存储
③在收到检查点完成的通知时,将所有结果一次性写入外部系统。
我们会发现,这种方式类似于检查点完成时做一个批处理,一次性的写入会带来一些性能上的问题;而优点就是比较简单,由于数据提前在状态后端中做了缓存,所以无论什么外部存 储系统,理论上都能用这种方式一批搞定。在 Flink 中 DataStream API 提供了GenericWriteAheadSink类,用来实现这种事务型的写入方式。
(2)两阶段提交(two-phase-commit,2PC)
顾名思义,它的想法是分成两个阶段:先做“预提交”,等检查点完成之后再正式提交。
这种提交方式是真正基于事务的,它需要外部系统提供事务支持。
具体的实现步骤为:
①当第一条数据到来时,或者收到检查点的分界线时,Sink 任务都会启动一个事务。
②接下来接收到的所有数据,都通过这个事务写入外部系统;这时由于事务没有提交,所
以数据尽管写入了外部系统,但是不可用,是“预提交”的状态。
③当 Sink 任务收到 JobManager 发来检查点完成的通知时,正式提交事务,写入的结果就
真正可用了。
当中间发生故障时,当前未提交的事务就会回滚,于是所有写入外部系统的数据也就实现了撤回。这种两阶段提交(2PC )的方式充分利用了 Flink 现有的检查点机制:分界线的到来,就标志着开始一个新事务;而收到来自 JobManager checkpoint 成功的消息,就是提交事务的指令。每个结果数据的写入,依然是流式的,不再有预写日志时批处理的性能问题;最终提交时,也只需要额外发送一个确认信息。所以 2PC 协议不仅真正意义上实现了 exactly-once ,而且通过搭载 Flink 的检查点机制来实现事务,只给系统增加了很少的开销。 Flink 提供 TwoPhaseCommitSinkFunction 接口,方便我们自定义实现两阶段提交的 SinkFunction 的实现,提供了真正端到端的 exactly-once 保证。

Flink 和 Kafka 连接时的精确一次保证

整体介绍

1Flink 内部

Flink 内部可以通过检查点机制保证状态和处理结果的 exactly-once 语义。

(2)输入端

输入数据源端的 Kafka 可以对数据进行持久化保存,并可以重置偏移量( offset )。所以我们可以在 Source 任务( FlinkKafkaConsumer )中将当前读取的偏移量保存为算子状态,写入到检查点中;当发生故障时,从检查点中读取恢复状态,并由连接器 FlinkKafkaConsumer Kafka重新提交偏移量,就可以重新消费数据、保证结果的一致性了。

(3)输出端

输出端保证 exactly-once 的最佳实现,当然就是两阶段提交( 2PC )。作为与 Flink 天生一对的 Kafka ,自然需要用最强有力的一致性保证来证明自己。
Flink 官方实现的 Kafka 连接器中,提供了写入到 Kafka FlinkKafkaProducer ,它就实现
TwoPhaseCommitSinkFunction 接口:

 实现端到端 exactly-once 的具体过程 

  1. 启动检查点保存: Source 任务会将检查点分界线(barrier)注入数据流。这个 barrier 可以将数据流中的数据,分为进入当前检查点的集合和进入下一个检查点的集合。\
  2. 算子任务对状态做快照 :分界线(barrier)会在算子间传递下去。每个算子收到 barrier 时,会将当前的状态做个快照,保存到状态后端。
  3. Sink 任务开启事务,进行预提交:分界线(barrier)终于传到了 Sink 任务,这时 Sink 任务会开启一个事务。接下来到来的所有数据,Sink 任务都会通过这个事务来写入 Kafka。对于 Kafka 而言,提交的数据会被标记为“未确认”(uncommitted)。这个过程就是所谓的“预提交”(pre-commit
  4. 检查点保存完成,提交事务:当 Sink 任务收到确认通知后,就会正式提交之前的事务,把之前“未确认”的数据标为“已确认”,接下来就可以正常消费了。

需要的配置

1)必须启用检查点;
(2)在 FlinkKafkaProducer 的构造函数中传入参数 Semantic.EXACTLY_ONCE;
(3)配置 Kafka 读取数据的消费者的隔离级别;
预提交阶段数据已经写入,只是被标记为“未提交”(uncommitted),而 Kafka 中默认的隔离级别 isolation.level 是 read_uncommitted,也就是可以读取未提交的数据。这样一来,外部应用就可以直接消费未提交的数据,对于事务性的保证就失效了。所以应该将隔离级别配置为 read_committed,表示消费者遇到未提交的消息时,会停止从分区中消费数据,直到消息被标记为已提交才会再次恢复消费。当然,这样做的话,外部应用消费数据就会有显著的延 迟。
(4)事务超时配置
Flink 的 Kafka连接器中配置的事务超时时间 transaction.timeout.ms 默认是 1小时,而Kafka集群配置的事务最大超时时间 transaction.max.timeout.ms 默认是 15 分钟。所以在检查点保存时间很长时,有可能出现 Kafka 已经认为事务超时了,丢弃了预提交的数据;而 Sink 任务认为还可以继续等待。如果接下来检查点保存成功,发生故障后回滚到这个检查点的状态,这部分数据就被真正丢掉了。所以这两个超时时间,前者应该小于等于后者。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用二叉树或栈求表达式的值--代码实现+算法分析

解决表达式求值问题有两种方法,一种是利用栈和后缀表达式求解,另一种是二叉树中序存储表达式。所以本文分为栈和二叉树两大部分带领读者求解表达式。 1. 利用栈解决表达式求值问题 所谓表达式,就是由变量、常量以及运算符组合而成的式子。其…

集群部署看过来,低代码@AWS智能集群的架构与搭建方案

亚马逊AWS是葡萄城的生态合作伙伴。为了帮助您充分利用AWS的托管服务快速构建起一套集群环境,彻底去掉“单一故障点”,实现最高的可用性,我们准备了**《低代码智能集群AWS的架构与搭建方案》**看完本文,带你掌握“基于nginx配置服…

Origin绘制多折线图

Origin的优势区间相对于python和R在于数据量大时处理方便 尤其是多维度、多线、多拟合 尝试复现上图 1.首先把20列数据复制过去 2.全选之后(ctrlA),然后点Plot——Line 3.随便选一根线,双击进入属性设置(Origin交互设…

计算机网络-传输层:TCP协议

目录 一、协议格式 二、协议特性 1.面向连接 1.1三次握手建立连接 1.2四次挥手断开连接 为什么握手是三次,挥手是四次? 三次握手失败后,两端如何处理? 一台主机上出现了大量CLOSE_WAIT状态连接的原因? TIME_W…

基于神经网络多项式插值的图像超分辨重构研究-附Matlab代码

⭕⭕ 目 录 ⭕⭕✳️ 一、引言✳️ 二、基于单帧图像的超分辨率重构技术✳️ 2.1 最近邻域插值法✳️ 2.2 双线性插值法✳️ 2.3 双三次插值法(Keys’插值)✳️ 三、神经网络插值原理✳️ 3.1 训练阶段:✳️ 3.2 测试阶段✳️ 四、实验验证✳️ 4.1 基于神经网络双线…

Hive、Impala、Hue集成LDAP

1.LDAP简介 轻型目录访问协议,是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息。在hadoop生态圈中,LDAP主要是用来做账号管理的。 2.LDAP安装配置 2.1 安装LDAP&#xf…

基于PHP+MYSQL宠物领养系统的开发与设计

市面上的宠物之家网站大多只是给爱宠人士一个交流的平台,给爱宠人士一个学习宠物习性,宠物购买的一个集合性的平台。很少有宠物领养功能,然而现在社会上有着太多的流浪宠物需要得到人们的关爱,这是很多宠物之家网站没有做到的。宠物之家网站正是顺应了当下的宠物热潮,为广大消费…

LeetCode | 1851.包含每个查询的最小区间

LeetCode | 1851.包含每个查询的最小区间 给你一个二维整数数组 intervals ,其中 intervals[i] [lefti, righti] 表示第 i 个区间开始于 lefti 、结束于 righti(包含两侧取值,闭区间)。区间的 长度 定义为区间中包含的整数数目&…

基于java+ssm+shiro的出租房管理平台

✌博主介绍✌:一个致力于全战开发的代码热爱者 龙门客栈管理平台一、前言介绍:二、系统设计:2.1 系统整体架构:2.1.1 数据库表结构的介绍:2.1.2 系统功能设计:三、功能截图:3.1 登录注册:3.2 基…

使用react-grid-layout和echarts-for-react实现一个支持拖拽的自定义响应式dashboard页面

使用react-grid-layout和echarts-for-react实现一个支持拖拽的自定义响应式dashboard页面 需求概要 在前端工作中,我们会经常遇到自定义dashboard页这样的需求。然后我想做一个能够让用户可以在面板上自由的拖拽,固定(不允许拖拽&#xff0…

游戏源码编程软件,对于新手来说十分友好,纯中文的界面让所有功能都一目了然,操作相当简单

这是一款免费的图像化编程工具,使用者无需会任何编程语言即可通过拼接积木的形式搭建出属于自己的程序。 编程猫kitten使用教程: 1、打开软件,进入软件主界面,运行界面如下图。 2、点击文件,可选择打开、新建、打开本地作品等。 3、可在方框内输入作品名称,快速进行输入…

安静!听听AI眼中岛国老师的声音~

大家好,我是鸟哥。一个半路出家的程序员。 最近在折腾自己的微信机器人,除了自动回复,自动拉群等常规的功能外,我准备给它赋予一些AI功能,毕竟这两年人工智能火的一塌糊涂。例如前段时间风靡朋友圈的人物头像动漫化&am…

如何保存/同步多架构容器 Docker 镜像

前言 随着容器、芯片技术的进一步发展,以及绿色、节能、信创等方面的要求,多 CPU 架构的场景越来越常见。典型的应用场景包括: 信创:x86 服务器 鲲鹏 ARM 等信创服务器;个人电脑:苹果 Mac M1 Windows 电…

Triton Inference Server 环境配置

本人环境 Ubuntu18.04,3090显卡,显卡驱动版本510.85.02,cuda版本11.6,docker版本20.10.12(注意:docker一定要通过apt安装,用snap安装会报错) 安装步骤 1. 根据驱动版本和cuda版本下载对应版本的Triton D…

java计算机毕业设计ssm驾校预约考试管理系统a3cf7(附源码、数据库)

java计算机毕业设计ssm驾校预约考试管理系统a3cf7(附源码、数据库) 项目运行 环境配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#…

第四章. Pandas进阶—日期数据处理

第四章. Pandas进阶 4.7 日期数据处理 1.DataFrame的日期数据转换(to_datetime) 在日常工作中,常见的日期方式有很多种,例如’20221123’,‘2022.11.23’,‘2022/11/23’,‘23/11/2022’&#…

Deepwalk详解

算法思想 源于word2vec ,word2vec通过语料库中的句子序列来描述词与词之间的共现关系。进而学习到词语的向量表示,deepwalk则使用图中的节点与节点的共像现关系来学习节点的向量表示。这种借鉴的前提是点在图中的分布和词在句子中的分布都是幂律分布。 …

关于MuLoginWebGL介绍说明:

WebGL就是俗称的硬件显卡型号的意思,在MuLogin中我们提供了多个平台和品牌的显卡芯片指纹。 我们在做实验时,Chrome浏览器和Internet Explorer(Edge)测试取WebGL vendor 会有两种不同值 ,Chrome 取为 Google Inc. Int…

2023年湖北监理工程师考试科目有哪些?考试题型什么样子的?

2023年湖北监理工程师考试科目有哪些?考试题型什么样子的? 一、监理工程师考试科目: 监理工程师考试一共考四科 1. 《建设工程监理基本理论和相关法规》(客观题) 2. 《建设工程合同管理》(客观题) 3. 《建设工程目标控制》(客观题) 4. 《…

社交电商时代,切勿剑走偏锋,始终以产品为中心,模式为辅助

社交电商这个名词近期十分火,参与这个方式的人数以亿计,可以这样说“十亿人民九亿商,八亿人在做电商”。 我们感悟:“传统电商火热,社交电商更火”!那么什么是社交电商呢?社交电商概念&#xff…