Apache Flink 流批融合技术介绍

news2024/11/15 13:47:19

摘要:本文整理自阿里云高级研发工程师、Apache Flink Contributor 周云峰老师在 Apache Asia CommunityOverCode 2024中的分享。内容主要分为以下三个部分:

  1. 从流批一体到流批融合
  2. 流批融合的技术解决方案
  3. 社区进展及未来展望

一、从流批一体到流批融合

1.流批一体

在流批融合之前,Flink 已经提出过流批一体的理念。流批一体主要体现在以下方面的统一:

(1)API 统一:Flink 通过提供统一的 DataStream 和 SQL API,使得用户在进行离线和在线作业时不需要开发两套代码,从而提升了开发效率。

(2)算子统一:在算子层面实现了统一,使用同一套算子既可以处理流作业,也可以处理批作业,确保流作业和批作业在数据处理逻辑、正确性和语义行为上保持一致。

(3)引擎统一:使用同一个引擎和同一套资源调度框架,避免了为流作业和批作业搭建不同工作流的需求,从而优化了运维效率。

这些都是 Flink 在流批一体方面已经取得的一些成果。然而,在现有流批一体的基础上,用户仍然需要配置一个作业是流作业还是批作业,并根据作业所在的离线或在线场景,采用不同的优化策略。这些配置策略仍然会一定程度上增加用户运维 Flink 作业的工作量。而这正是流批融合希望解决的问题。

2. 影响流批不同模式的前提条件

在流批融合的背景下,通过分析用户配置流模式和批模式的思路,我们发现流批两种模式,实际上是根据不同的前提条件采用不同的优化策略。这些前提条件主要包括以下两个方面:

(1)用户对性能的倾向性:在配置批作业时,用户通常倾向于追求高吞吐量或高资源利用率。而在流作业中,用户则期望低延迟、高数据新鲜度和实时性。

(2)对数据的先验知识:在批模式下,所有数据在一开始都是已准备好的,因此作业可以根据数据的一些统计信息进行相应的优化。而在流模式下,由于作业通常不知道未来会有哪些数据,因此需要对随机访问等领域进行优化,以提供更好的支持。

由于前提条件不同,Flink 在流模式和批模式下采取了不同的优化策略。这些策略主要体现在资源调度、状态访问和容错机制等方面:

(1)资源调度(Scheduling)

  • 批作业:可以做到见缝插针式的资源使用方式。即使当前物理资源不满足所有算子同时执行的需求,也可以先利用现有资源执行一部分任务(task)。任务执行完后空出的资源可以调度下一批任务,从而提高资源利用率。

  • 流作业:为了保证更好的实时性,流作业需要在一开始就申请好从源头(source)到终点(sink)的所有算子及其并发资源,以确保数据流的连续性和低延迟。

(2)状态访问(State Access)

  • 批作业:可以只保存一个主键对应的状态,并连续处理该主键的所有数据。

  • 流作业:由于无法预知下一个相同主键的数据何时到来,需要保存所有主键的状态,并对随机访问进行优化,以支持实时处理。

(3)容错机制(Fault Tolerance)

  • 批作业:在每个任务执行完之后,Flink作业可以暂时将中间结果缓存下来,然后下一个任务可以接着消费这个中间结果。当某个任务失败时,只需重启该任务,并从之前保存的中间结果重新消费即可。

  • 流作业:Flink引入了检查点(checkpoint)机制,通过定时对整个数据处理链路进行快照,实现容错。当某个任务失败时,可以从最近的检查点恢复,从而保证数据处理的连续性和一致性。

由于这些不同的前提条件,Flink在流模式和批模式下本质上采用了不同的优化策略,以满足各自的性能需求和操作特点。

3.前提条件的动态变化

在进一步的探索中,我们发现这些前提条件并不是在作业的整个生命周期中一成不变、而是可能会在运行时动态变化的。

  • 在离线场景中,作业场景一般始终具有高吞吐量的倾向。

  • 而在实时场景下,用户通常更注重低延迟、高实时性和高数据新鲜度。然而,当实时场景出现数据积压时,由于客观因素的限制,Flink 作业此时已经无法维持端到端的低延迟策略。这时,用户追求的是以最短时间消费完现有的数据积压、尽快恢复到实时状态,即高吞吐量策略。

  • 在全增量一体化的场景中,这两种模式的区别进一步被细化为全量和增量的区别。在这两种状态下,除了对吞吐量和实时性的要求不同外,还有关于数据先验知识的变化。在同步一个全量数据库的场景下,所有数据之间的主键不会重复,是对整个数据库进行一次全面扫描。而在增量场景下,可能会出现更新操作,对已有的重复主键进行数据更新。

这些说明我们需要 Flink 能够根据作业运行时需求的动态变化,产生不同的优化策略。

4.流批融合的目标

基于以上对前提条件和场景的分析,我们可以看到,流批融合想要实现的目标是使用户不再需要手动配置流模式或批模式,而是通过 Flink 框架自动检测用户在不同场景下(实时和离线)对吞吐量、延迟以及数据特征的需求,动态地进行相应的优化。这使得 Flink 能够根据用户对吞吐量和延迟的倾向性,以及数据特征的变化,自动调整优化策略。

二、实现流批融合的技术方案

下面介绍Flink是怎样实现这些目标的。

1.数据流批倾向性的定量指标

首先,我们将用户的倾向性或数据特征量化为两个指标。

第一个指标是 isProcessingBacklog,可以理解为用于判断当前是否存在数据积压。当出现数据积压时,作业需要在最短时间内处理这些积压数据。这时,作业可以通过牺牲延迟来优化,从而提高吞吐量。在没有数据积压的情况下,作业应该像现有的流模式那样,尽量保证低延迟和高数据新鲜度的目标。

第二个量化指标是 isInsertOnly,可以大致理解为全增量一体中全量场景和增量场景之间的区别。在 isInsertOnly 情况下,所有数据都会是 Insert 类型,而不是更新(update)或删除(delete)类型的数据。这些数据的主键也互不重复。

2.量化指标的收集

怎样去收集获取刚才提到的两个量化指标呢?一个主要的思路是从数据源(source)获取数据。

例如,对于有明确阶段的数据源(如Hybrid Source),它可能会先读取文件系统中的一个文件,将全量文件读取完毕后,再消费实时消息队列中的数据。在这种情况下,初始阶段消费文件时,作业总会存在数据积压,此时isProcessingBacklog = true;而在后续阶段消费消息队列时,isProcessingBacklog 才会从 true 变为 false。

对于 CDC source 也是类似。在全量场景下,isProcessingBacklog 等于 true,而在增量场景下则等于 false。

对于没有明确阶段的源(如普通的消息队列),作业可以根据 Flink 现有的一些指标(metrics)来判断是否存在数据积压,例如 Watermark 延迟。Watermark 代表作业数据时间的当前水位,其时间戳与系统时间之间的差异表现为 Watermark 延迟。当延迟高于一定阈值时,说明当前存在数据积压;反之,则没有数据积压。

前面介绍了判断 isProcessingBacklog 的方法。而对于判断 isInsertOnly 的方式,目前主要支持 CDC source。在全量阶段,isInsertOnly 等于 true,而在增量阶段,isInsertOnly 等于 false。

3.基于量化指标的优化策略

在收集到这些指标后,接下来要做的是在各个算子中根据当前这两个指标的状态,采用不同的优化策略。

(1)Processing Time Temporal Join

首先,对于 isProcessingBacklog,优化措施之一是更好地支持基于处理时间的临时连接(Processing Time Temporal Join)。这种 Join 不依赖于 Probe Side 和 Build Side 数据本身的时间因素,而是依赖于系统时间。当Probe Side数据到达Flink系统时,根据当前最新的 Build Side 数据做 Join 即可。

这种做法在语义上没有问题,但在实际操作中可能会遇到以下情况:当 Build Side 有数据积压时,有可能某条数据已经被更新到 Build Side 上游的服务中了,但由于数据积压,这条数据无法及时被Flink系统接收到。此时当 Probe Side 的一条数据过来进行 Join 时,就可能无法与这条数据进行匹配,从而导致Join结果不包含预期中的所有数据。

为了解决这个问题,Flink 采取的优化措施是: 当 Build Side 存在数据积压,即 isProcessingBacklog 等于 true 时,Join 算子先暂停消费 Probe Side 的数据。等作业追上 Build Side 的数据后,Join 算子再继续消费 Probe Side 的数据,从而避免之前提到的 Join 丢失情况。

(2)调整checkpoint时间间隔

第二个优化是调整 Flink 的 checkpoint 时间间隔。以 Paimon Sink 为例,Flink 的一些 Connector 能够保证数据 exactly-once 的语义,并且其 exactly-once 语义依赖于二阶段提交能力。而 Paimon Sink 二阶段提交的频率和 Flink 的 checkpoint 时间间隔保持一致。

因此,这里进行了一个优化:当 isProcessingBacklog 为 true 或 false 时,用户可以分别设置不同的 checkpoint 时间间隔。当数据积压时,用户可以配置一个较长的时间间隔,以尽量减少 Paimon Sink 执行二阶段提交的次数及其开销。通过这种方式,Paimon Sink 能够增加全量数据同步阶段的吞吐量。

(3)优化数据的处理顺序

另一个基于 isProcessingBacklog 的优化是对输入数据进行排序。前面提到,批处理作业相比于流处理作业的一个优势在于可以连续消费同一个主键的数据,在本地的 Flink 算子中只需要保存一个主键所对应的状态,不需要有随机访问 Key-Value Store的开销。受此启发,我们将这种优化应用到流处理作业上。

具体来说,当 isProcessingBacklog 为 true 时,下游算子会先暂停消费数据,然后对上游积压的数据进行排序。排序完成后,算子再对相同主键的数据进行连续消费。这样不仅不会明显增加数据延迟,还通过减少随机访问状态后端的开销,优化了作业的整体吞吐量。

(4)基于isInsertOnly优化Sink行为

关于 isInsertOnly 的优化,目前看到的主要应用在 Paimon sink 和 Hologres sink 上。首先,Paimon sink 除了更新数据本身以外,还支持生成变更日志(changelog)。在通常情况下,changelog 和数据文件之间的关系可以理解为:changelog 是原始的输入数据,而数据文件是对原始输入数据进行去重和更新后的结果。

在 isInsertOnly 为 true 的情况下,因为所有数据的主键都不同,我们可以认为 changelog 去重过程实际上并没有进行去重操作,changelog 和数据文件的内容是相同的。基于这一信息,Paimon sink 可以不需要独立地进行序列化、格式转换、分别写出 changelog 文件和数据文件;相反,Paimon sink 只需要写出一份数据文件,然后再拷贝一份作为 changelog 文件即可。这样做减少了 CPU 的开销。

类似的优化也可以应用在 Hologres sink上。在 isInsertOnly 为 true 的情况下,Hologres sink可以使用批量插入(batch insert)并避免预写日志(write-ahead logging)这些步骤。当写入一条数据时,作业不需要查询数据库中是否存在该主键的数据来决定是更新现有数据还是插入一条新数据,因为isInsertOnly 语义已经保证不会出现主键重复的情况。因此作业可以跳过这些查询和更新的开销,从而实现吞吐量的优化。

三、社区进展以及未来展望

最后介绍上面提到的这些优化,它们现在的一些进展以及未来展望。

1.isProcessingBacklog进展

首先,关于 isProcessingBacklog,目前社区已经完成了根据 source 的不同阶段生成 isProcessingBacklog 信号,并将这个信号传递到下游、用它来调控 Flink 的 checkpoint 时间间隔的部分。对于前面提到的对所有数据进行排序以减少状态开销、以及根据 watermark 的延迟来判断 isProcessingBacklog 的功能,它们已经在社区中提出讨论,但还没有最终完成。这里每个条目后都有对应的 Flink 设计文档编号,感兴趣的读者可以参考相关的具体设计文档。

2.isInsertOnly进展

关于 isInsertOnly,前面介绍到的内容,包括从 CDC(Change Data Capture)收集 isInsertOnly 信号,并利用该信号优化 Paimon Sink 和 Hologres Sink的部分,这些功能已经在阿里云商业化版本的 Flink 中完成,并预计将在下个版本发布。

另外,isInsertOnly 信号的语义与 Flink 社区的部分现有框架还存在一些冲突,相关冲突预计将在 Flink 2.0 支持 Generalized Watermark 机制后自然解决。因此,目前我们先在阿里云的商业化版本中实现了这些优化,待 Flink 2.0 支持相应的基础设施后,我们会将这些优化推向 Flink社区。

3.未来展望

未来,我们将进一步推进以下几个方面的工作:

(1)在 Flink 2.0 中推向社区的优化:我们计划将关于 isInsertOnly 的优化推向 Flink 社区。这些优化已经在阿里云商业化版本中完成,并预计将在 Flink 2.0 支持 Generalized Watermark 机制后逐步推向社区。

(2)动态修改 Flink 的算子流程结构(DAG 图):我们将探索根据用户在不同阶段的需求(流模式或批模式)动态修改 Flink 的算子流程结构(DAG 图)的支持,以更好地适应不同的应用场景。

(3)改进量化指标的切换机制:目前对于 isProcessingBacklog/isInsertOnly 信号,我们只支持一次性的切换,即对于需要追溯历史数据或同步全量数据的作业,目前支持在初始化阶段 isProcessingBacklog/isInsertOnly 设置为 true,在追上实时或增量数据后一次性切换为 false。在未来,我们希望即使在量化指标切换为 false 后,Flink作业仍然能够根据实际过程中偶尔出现的数据积压情况,再从false切换回true,重新应用批处理的优化。这将使系统更具灵活性和适应性。

以上就是我们未来的一些优化思路。欢迎大家加入阿里云的开源大数据团队,共同推动技术进步和创新。

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

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

相关文章

记忆化搜索专题——算法简介力扣实战应用

目录 1、记忆化搜索算法简介 1.1 什么是记忆化搜索 1.2 如何实现记忆化搜索 1.3 记忆化搜索与动态规划的区别 2、算法应用【leetcode】 2.1 题一:斐波那契数 2.1.1 递归暴搜解法代码 2.1.2 记忆化搜索解法代码 2.1.3 动态规划解法代码 2.2 题二&#xff1…

网络模型的保存与读取

文章目录 一、模型的保存二、文件的加载三、模型加载时容易犯的陷阱 一、模型的保存 方式1:torch.save(vgg16, “vgg16_method1.pth”) import torch import torchvision.modelsvgg16 torchvision.models.vgg16(pretrainedFalse) torch.save(vgg16, "vgg16_method1.pth…

oracle数据库启动

文章目录 背景一、步骤1.登录oracle用户2.启动监听服务3.启动数据库 背景 oracle数据库启动 一、步骤 1.登录oracle用户 代码如下(示例): su - oracle2.启动监听服务 代码如下(示例): lsnrctl start成…

【C++】STL----vector常见用法

🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:C从小白到高手 🌹往期回顾🌹:[C]string类 🔖 流水不争,争的是滔滔不息。 文章目录 一、vector的介绍vector…

MATLAB绘图基础8:双变量图形绘制

参考书:《 M A T L A B {\rm MATLAB} MATLAB与学术图表绘制》(关东升)。 8.双变量图形绘制 8.1 散点图 散点图用于显示两个变量间的关系,每个数据点在图上表示为一个点,一个变量在 X {\rm X} X轴,一个变量在 Y {\rm Y} Y轴&#…

【Python报错已解决】AttributeError: ‘DataFrame‘ object has no attribute ‘append‘

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

暴雨信息|《2024 年全球人工智能趋势报告》发布,GPU仍是AI发展最大关键之一

全球著名调研机构WEKA近日正式发布《2024年全球人工智能趋势报告》,该报告是基于全球1500人工智能决策者的深度调查,覆盖金融、政府、医疗保健等多个行业,解锁了人工智能领域的关键见解和策略。 人工智能正成为许多组织战略的一个基本面&…

滑动窗口(8)_最小覆盖字串

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 滑动窗口(8)_最小覆盖字串 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. 题…

6.C++程序中的基本数据类型

数据类型是指在C中用于声明不同类型变量或函数的一个系统或抽象或者是一个分类,它决定了变量存储占用的内存空间以及解析存储的位模式。其实数据类型可以理解为固定内存大小的别名,是创建变量的模具,具体使用哪种模具(包括自定义&…

基于深度学习的文本情感原因提取研究综述——论文阅读

前言 既然要学习情感分析,那么肯定还要了解情感原因对抽取的发展历程,所以我又搜了一篇研究综述,虽然是2023年发表的,但是里面提及到的历程仅停留到2022年。这篇综述发布在TASLP期刊,是音频、声学、语言信号处理的顶级…

进程间的通信-信号量

信号量 1.资源竞争 资源竞争 : 当多个进程同时访问共享资源时,会产生资源竞争,最终最导致数据混乱临界资源 : 不允许同时有多个进程访问的资源,包括硬件资源(CPU、内存、存储器以及其他外围设备)与软件资源(共享代码段、共享数据结构)临界区…

有关JS下隐藏的敏感信息

免责声明:本文仅做分享! 目录 JavaScript 介绍 核心组成 工具 FindSomething ** 浏览器检查 ** LinkFinder URLfinder ** SuperSearchPlus ** ffuf ParasCollector waymore Packer Fuzzer JS逆向 应用: 小结: Ja…

基于Python+SQLite的课程管理系统

系统需求简介 1.1需求分析 实现一个具体的课程管理系统。按照软件工程思路设计简化的专业课数据库,尽量模拟现有专业课程一个学期的选课排课原型实际情况。(注:本系统由本人单独设计、开发完成) 1.2 数据结构需求分析 课程管理…

NAND闪存:迎来新的发展机遇

2024年,存储市场正在经历着动态的变化,其中包括合同价格的上涨、制造商营收的增长以及多项技术上的突破。在这个背景下,主要的存储公司正在为新的挑战做准备,尤其是在NAND闪存领域即将面临转型的情况下。 扩展阅读:20…

PMData:人工智能之运动记录数据集

简介 在这个数据集中,我们展示了 PMData 数据集,旨在将传统的生活记录与体育活动记录相结合。这样的数据集可以开发几个有趣的分析应用程序,例如,可以使用额外的运动数据来预测和分析日常发展,如人的体重和睡眠模式&a…

数据飞轮:打造业务增长的持续循环

在当今数据驱动的世界中,企业必须利用数据的力量才能保持竞争力。然而,仅仅收集和分析数据是不够的;企业必须能够从他们的数据中创造一个持续增长的循环,才能保持成功。其中一种方法就是创建数据飞轮。接下来让我们来探讨一下什么…

centos7如何连接网络 centos7wifi连接

这段时间重新学习 Linux 知识,用的是笔记本,连接的是无良房东家的 WiFi,IP地址经常变动。每次都要修改 Xshell 的配置才能连上虚拟机。效率很低。 为此,必须要解决这个 IP 地址经常变动的事情!这里讲解的版本是&#…

Java集成gdal 处理解析tiff和shp数据

1. 配置 gdal 1.1. 官网下载 这个是因为你电脑是 win64 位才选择哦~ 下载这个,然后解压 1.2. 复制这个压缩包下的 ddl 文件 可以按照类型复制,然后复制到你的 java jDK 文件夹下 1.3. 找到你的 java jdk 文件夹 不知道 java 的文件夹位置…

数字签名和CA数字证书的核心原理

看了蛋老师的视频就很容易理解了,首先对服务器的公钥和信息进行哈希运算得到一个短字符串,然后用CA机构中的私钥对这一短字符串进行加密就得到了一个数字签名,然后就这个数字签名放到数字证书中,同时服务器的公钥也放在数字证书中…

NFT Insider #148:The Sandbox 推出 SHIBUYA Y3K 时尚系列,Azuki 进军动漫 NFT 领域

市场数据 加密艺术及收藏品新闻 Infinex 新推 NFT 系列首四日销售额破4000万美元 尽管顶级 NFT 系列表现不佳,Infinex 的最新 NFT 系列在首四日内销售额已超过 4000 万美元。Infinex 是一个非托管平台,提供轻松访问链上协议和 dApp。 Infinex Core 的…