欢迎来到皮皮网官网

【闲约源码】【sola算法源码】【重锤坠地 源码】flink并行源码_flink 并行

时间:2024-12-23 02:20:11 来源:复制病毒源码

1.flink����Դ��
2.Flink常见面试问题(原理)
3.10-flink TaskManager 和 Slots
4.Flink深入浅出:JDBC Connector源码分析
5.Flink是并并行什么意思?
6.Flink入门-定义、架构和原理

flink并行源码_flink 并行

flink����Դ��

       Apache Flink是行源一个处理框架,专为实时和离线数据流的并并行复杂状态计算设计,旨在提供低延迟、行源高吞吐量、并并行准确性和容错性的行源闲约源码处理能力。

       批处理作为其特殊类型,并并行Flink旨在通过并行处理和分布式架构来优化性能。行源

       快速上手Flink,并并行可选择在Standalone模式部署,行源通过slot(资源分配的并并行基本单位)来分配资源,或者在生产环境中利用YARN(容器化资源管理)和Hadoop。行源session-cluster模式适用于小规模短时作业,并并行而per-job-cluster模式则适合大型长期作业,行源甚至在Kubernetes上运行,并并行以简化运维。

       Flink的运行架构包括客户端提交任务,通过HDFS和YARN进行资源管理。任务首先由JobManager调度至TaskManager,TaskManager之间通过流式通信。客户端负责数据流的准备和提交,而JobManager和TaskManager作为独立的JVM进程运行。

       Flink的流处理API基于数据流的链式结构,包括数据源、转换和sink。算子的并行度决定了子任务的数量。对于数据处理,Flink支持多种数据源,如Kafka、Redis、Elasticsearch和自定义JDBC sink。窗口功能将无限流分割为有限流,sola算法源码便于分析。

       EventTime和Watermark机制在处理乱序数据时至关重要,通过设置Watermark的延迟,Flink确保数据的准确处理和迟到数据的处理。ProcessFunction API允许开发者访问时间戳、Watermark,以及创建自定义事件驱动应用和业务逻辑。

       Flink的核心容错机制是一致性检查点,通过保存任务处理状态实现故障恢复。除了检查点,用户还可以利用保存点进行备份、更新或迁移应用。状态一致性保证了流处理结果的准确性,而端到端的数据保证则确保了整个处理过程的可靠性。

Flink常见面试问题(原理)

       Flink面试中常见的问题概述

       Flink任务提交流程涉及以下几个步骤:

       当部署在YARN上时,首先由Client将Flink的Jar包和配置上传到HDFS,接着向YARN的ResourceManager提交任务。

       ResourceManager分配Container资源后,会通知NodeManager启动ApplicationMaster。ApplicationMaster负责启动JobManager,加载和配置后,它会申请资源启动TaskManager。

       TaskManager在NodeManager的指导下启动,向JobManager发送心跳并等待任务分配。

       Flink的执行图包括四个阶段:StreamGraph、JobGraph、ExecutionGraph和物理执行图。StreamGraph表示代码的拓扑结构,JobGraph是经过优化的并行版本,而ExecutionGraph是根据并行度进行规划的核心结构,最后的重锤坠地 源码物理执行图将任务分配给实际的TaskSlot运行。

       关于slot和任务的关系,一个任务所需的slot数量取决于并行度最大的算子,而并行度和slot数量是两个不同的概念:并行度是动态配置的,而slot数量是TaskManager的静态配置。

       Flink通过任务链(Operator Chains)技术优化算子间的连接,减少序列化/反序列化等开销,提高性能。

       Flink的SQL部分依赖Apache Calcite进行校验、解析和优化,SQL解析过程涉及复杂步骤。

       在数据抽象和交换方面,Flink通过MemorySegment和相关的数据转换类来管理内存,避免JVM的性能瓶颈。

-flink TaskManager 和 Slots

       æ€è€ƒé—®é¢˜:

        1.怎么样实现并行计算?

        答:设置并行度。多线程,不同任务放到不同线程上。

        2.并行的任务,需要占用多少slot?

        3.一个流处理程序,到底包含多少个任务?

        一、TaskManager和Slot的关系介绍

        process:进程

        Treads:线程

        二、并行度(parallelism)

        每一个线程占用一个slot,上图一中任务合并为上图二所示(任务链,后续讲解),图中算子并行度最大的(算子后面的中括号数字代表并行度)为2,所以整个flink程序的并行度为2,所以只需要2个slot就可以跑起来。

         One-to-one:

        stream(比如在source和map operator之间)维护着分区以及元素的顺序。那意味着flatmap 算子的子任务看到的元素的个数以及顺序跟source 算子的子任务生产的元素的个数、顺序相同,map、fliter、flatMap等算子都是one-to-one的对应关系。类似于spark中的窄依赖

         Redistributing:

        stream(map()跟keyBy/window之间或者keyBy/window跟sink之间)的分区会发生改变。每一个算子的子任务依据所选择的transformation发送数据到不同的目标任务。例如,keyBy()基于hashCode重分区、broadcast和rebalance会随机重新分区,这些算子都会引起redistribute过程,而redistribute过程就类似于Spark中的shuffle过程。类似于spark中的宽依赖

        图中:A4 代表 A任务有4个,C2表示C任务2个,以此类推

        taskmanager.numberOfTaskSlots:3 每个taskmanager设置了并行度为3

        设一共有3个TaskManager,每一个TaskManager中的分配3个TaskSlot,也就是每个TaskManager可以接收3个task,一共9个TaskSlot,如果我们设置parallelism.default=1,即运行程序默认的并行度为1,9个TaskSlot只用了1个,有8个空闲,因此,设置合适的并行度才能提高效率。

        三、思考

        假设当前可用的slot只有1个,任务有4个,slot不够用的时候,则会一直等待分配资源,直到超时报错。

        slot推荐设置为当前机器的核心数,假设cpu核心数为4核,则设置4。

        slot占用数量与并行度最大的算子一致。

Flink深入浅出:JDBC Connector源码分析

       大数据开发中,数据分析与报表制作是日常工作中最常遇到的任务。通常,我们通过读取Hive数据来进行计算,并将结果保存到数据库中,然后通过前端读取数据库来进行报表展示。然而,使用FlinkSQL可以简化这一过程,通过一个SQL语句即可完成整个ETL流程。

       在Flink中,读取Hive数据并将数据写入数据库是常见的需求。本文将重点讲解数据如何写入数据库的过程,包括刷写数据库的机制和原理。

       以下是本文将讲解的几个部分,以解答在使用过程中可能产生的疑问:

       1. 表的定义

       2. 定义的表如何找到具体的实现类(如何自定义第三方sink)

       3. 写入数据的机制原理

       (本篇基于1..0源码整理而成)

       1. 表的定义

       Flink官网提供了SQL中定义表的示例,以下以oracle为例:

       定义好这样的表后,就可以使用insert into student执行插入操作了。接下来,源码泄露 swp我们将探讨其中的技术细节。

       2. 如何找到实现类

       实际上,这一过程涉及到之前分享过的SPI(服务提供者接口),即DriverManager去寻找Driver的过程。在Flink SQL执行时,会通过translate方法将SQL语句转换为对应的Operation,例如insert into xxx中的xxx会转换为CatalogSinkModifyOperation。这个操作会获取表的信息,从而得到Table对象。如果这个Table对象是CatalogTable,则会进入TableFactoryService.find()方法找到对应的实现类。

       寻找实现类的过程就是SPI的过程。即通过查找路径下所有TableFactory.class的实现类,加载到内存中。这个SPI的定义位于resources下面的META-INFO下,定义接口以及实现类。

       加载到内存后,首先判断是否是TableFactory的实现类,然后检查必要的参数是否满足(如果不满足会抛出异常,很多人在第一次使用Flink SQL注册表时,都会遇到NoMatchingTableFactoryException异常,其实都是因为配置的属性不全或者Jar报不满足找不到对应的TableFactory实现类造成的)。

       找到对应的实现类后,调用对应的createTableSink方法就能创建具体的实现类了。

       3. 工厂模式+创建者模式,创建TableSink

       JDBCTableSourceSinkFactory是JDBC表的具体实现工厂,它实现了stream的sinkfactory。在1..0版本中,它不能在batch模式下使用,但在1.版本中据说会支持。这个类使用了经典的html源码示例工厂模式,其中createStreamTableSink负责创建真正的Table,基于创建者模式构建JDBCUpsertTableSink。

       创建出TableSink之后,就可以使用Flink API,基于DataStream创建一个Sink,并配置对应的并行度。

       4. 消费数据写入数据库

       在消费数据的过程中,底层基于PreparedStatement进行批量提交。需要注意的是提交的时机和机制。

       控制刷写触发的最大数量 'connector.write.flush.max-rows' = ''

       控制定时刷写的时间 'connector.write.flush.interval' = '2s'

       这两个条件先到先触发,这两个参数都是可以通过with()属性配置的。

       JDBCUpsertFunction很简单,主要的工作是包装对应的Format,执行它的open和invoke方法。其中open负责开启连接,invoke方法负责消费每条数据提交。

       接下来,我们来看看关键的format.open()方法:

       接下来就是消费数据,执行提交了

       AppendWriter很简单,只是对PreparedStatement的封装而已

       5. 总结

       通过研究代码,我们应该了解了以下关键问题:

       1. JDBC Sink执行的机制,比如依赖哪些包?(flink-jdbc.jar,这个包提供了JDBCTableSinkFactory的实现)

       2. 如何找到对应的实现?基于SPI服务发现,扫描接口实现类,通过属性过滤,最终确定对应的实现类。

       3. 底层如何提交记录?目前只支持append模式,底层基于PreparedStatement的addbatch+executeBatch批量提交

       4. 数据写入数据库的时机和机制?一方面定时任务定时刷新,另一方面数量超过限制也会触发刷新。

       更多Flink内容参考:

Flink是什么意思?

       Flink,全称为Apache Flink,是一个开源的流处理框架,由Apache软件基金会开发,特别强调高吞吐量、低延迟和容错处理。核心是基于Java和Scala的分布式流数据引擎,它采用数据并行和流水线方式执行流数据程序,同时支持批处理和迭代算法。Flink的特点在于其容错能力,即使在机器故障时也能保证exactly-once的语义,即数据处理的精确性。

       Flink的数据流引擎支持事件时间处理和状态管理,其应用程序能够处理无限数据集,程序可以使用Java、Scala、Python和SQL等多种编程语言编写。它并不内置数据存储系统,而是与Amazon Kinesis、Apache Kafka、HDFS等外部存储系统无缝集成,提供了数据源和接收器的连接。

       Flink编程模型基于流和转换,将数据流视为可能无限的记录流,通过一系列操作如过滤、聚合和窗口函数进行处理。它有两种核心API,包括数据流API处理无界和有界数据,以及数据集API处理有界数据集。Flink还提供表API和SQL语言,让关系流和批处理变得更加直观和易用。

       Flink的分布式执行模型将程序映射成数据流图,允许分支和合并数据流,内置的连接器支持多种数据源和接收器,如Kafka和HDFS。Flink程序能够作为分布式系统在集群中运行,也能独立部署或借助YARN、Mesos等资源管理框架。

       Flink的容错机制以分布式检查点为核心,自动保存应用状态和数据流位置,确保故障恢复时的一致性。此外,还提供了手动触发的保存点机制,允许在不影响状态的情况下更新程序或集群。对于有状态的流处理,如5秒窗口内的字数计数,Flink的数据流API提供了相应的函数支持。

       总的来说,Apache Flink是一个强大且灵活的流处理框架,适用于多种场景,包括实时和批量数据处理,以及状态管理和容错处理。

Flink入门-定义、架构和原理

       Flink是一个开源的大数据框架,主要用于在无界和有界流数据上执行有状态计算。其适用于实时性要求高的应用,如预警、实时数量统计、数据库交互、跟踪和基于数据流的机器学习场景。

       流数据处理的原理涉及延迟、吞吐量和数据流模型。事件时间表示数据产生时的原设备时间戳,处理时间则表示流处理程序处理数据时的时间戳。数据流图描述了流数据在不同算子之间流转的过程,数据分配策略包括转发、基于Key、随机和广播策略。

       流处理操作包含流数据源、转换和输出。窗口操作接收并缓冲数据后触发计算,分为滚动、滑动和会话窗口。滚动窗口按固定大小拆分数据,滑动窗口有交叉,会话窗口根据时间间隔划分窗口。

       在流处理应用中,Flink能够实现低延迟和高吞吐能力的平衡,通过分布式并行计算。其数据流模型提供基于事件时间、水位线和延迟处理的机制,实现窗口聚合计算,以确保计算的正确性、高吞吐和延迟之间的平衡。

Flink之工作原理

       Flink作为新的stream计算引擎,这两年社区的活跃度很高。对于Flink 既可以处理stream data也可以处理batch data,同时可以兼顾Spark以及Sparkstreaming的功能,与Spark不同的是,Flink本质上只有stream的概念,batch被认为是special stream。Flink主要有以下几个角色需要大家了解,对于Flink的开发是很有帮助的。也便于自己后期翻阅。

       JobClient:

        负责接收程序,解析和优化程序的执行计划,然后提交执行计划到JobManager。这里执行的程序优化是将相邻的Operator融合,形成OperatorChain,Operator的融合可以减少task的数量,提高TaskManager的资源利用率。

        JobManagers:

        负责申请资源,协调以及控制整个job的执行过程,具体包括,调度任务、处理checkpoint、容错等等

        TaskManager:

        TaskManager运行在不同节点上的JVM进程(process),负责接收并执行JobManager发送的task,并且与JobManager通信,反馈任务状态信息,如果说JobManager是master的话,那么TaskManager就是worker用于执行任务。每个TaskManager像是一个容器

        ,包含一个或者多个Slot。

        Slot:

        Slot是TaskManager资源粒度的划分,每个Slot都有自己独立的内存。所有Slot平均分配TaskManager的内存,值得注意的是,Slot仅划分内存,不涉及cpu的划分。每个Slot可以运行多个task。Slot的个数就代表了一个程序的最高并行度。

        Task:

        Task是在operators的subtask进行链化之后形成的,具体Flink job中有多少task和operator的并行度和链化的策略有关,为了方便大家理解,可以参考图5中所示的理解。

        SubTask:

        因为Flink是分布式部署的,程序中的每个算子,在实际执行中被分隔为一个或者多个subtask,运算符子任务(subtask)的数量是该特定运算符的并行度。数据流在算子之间流动,就对应到SubTask之间的数据传输。Flink允许同一个job中来自不同task的subtask可以共享同一个slot。每个slot可以执行一个并行的pipeline。可以将pipeline看作是多个subtask的组成的。

        Flink程序本质上是并行和分布式的。在程序执行期间,一个流会生成一个或者多个stream partition,并且一个operator会生成一个或者多个operator subtask。operator的 subtask 彼此之间是独立的,分别在不同的线程里去执行并且可能分布在不同的机器上或者containers上。

        operator的subtasks的数量等于该操作算子的并行度的数量。流的并行度有总是取决于产生它的操作算子的并行度决定的。同一个flink程序中的不同的operators可能有不同的并行度。

        数据流在两个operators之间进行传递的方式有两种:one-to-one 模式 和 redistributing 模式

        ①:one-to-one 模式:两个operator用此模式传递的时候,会保持数据的分区数和数据的排序,比如:在下图中Source和map() operators之间的数据传递方式;

        ②:Redistributing 模式:这种模式会改变数据的分区数;每个一个operator subtask会根据选择transformation把数据发送到不同的目标subtasks,比如keyBy()会通过hashcode重新分区,broadcast()和rebalance()方法会随机重新分区,比如:在下图中map()和keyBy/window ,keyBy/window和Sink之间的数据传递方式;

        对于分布式计算,Flink将operator 的subtasks链化在一起形成tasks。每个task在一个线程中被执行。将operators链化在一起形成tasks是比较好的一个优化:他减少了线程和线程之间的切换和缓冲的开销,增加了吞吐量降低了延迟。对于operator的链化行为,可以根据个人来去调整。详情参考 官网

        下图中operators经过链化之后,仅仅需要5个并行的线程。

        ①每一个worker(TaskManager) 都是一个JVM进程,他可能会在独立的线程中执行一个或者多个subtask。为了控制worker能够接收多个task。worker通过task slot来进行控制(一个worker至少有一个task slot)。

        ②每个task slot表示TaskManager拥有资源的一个固定大小的子集。假如一个TaskManager有三个slot,那么它会将其管理的内存分成三份给各个slot。slot的资源化意味着一个job的subtask将不需要跟来自其它job的subtask竞争被管理的内存。

        ③通过调整task slots的数量,用户可以定义subtasks它们之间如何互相隔离。如果一个TaskManager一个slot,那将意味着每个task group独立的运行在JVM中。而一个TaskManager多个slot意味着更多的subtask可以共享一个JVM。而在同一个JVM进程中的task将共享TCP连接和心跳消息。它们也可能共享数据集和数据结构,这样可以减少每个task的负载。

        默认,如果subtask是来自相同的job,但不是相同的task,Flink允许subtask共享slot。这样就会出现一个slot可能容纳一个job中的整个pipeline。允许slot共享有以下两个好处:

        ① Flink集群需要的task slots的数量和作业中的最高并行度的一致。不需要计算一个程序总共包含多少个task。

        ②更好的利用资源。如果没有slot共享,非密集型source/map()子任务将阻塞与资源密集型窗口子任务一样多的资源;在slot共享的话,将我们图6的示例中的基本并行度从2提高到6,可以充分利用slot资源,同时确保繁重的subtasks在Taskmanager中公平分配。

Flink的并行度(Parallelism)

       Flink程序在执行时,展现并行和分布式特性。流包含一个或多个分区,每个算子可包含一个或多个子任务,这些子任务在不同线程、物理机或容器中独立执行。特定算子子任务数量即为该算子并行度。通常,程序并行度为所有算子中最大值,不同算子可能具有不同并行度。

       数据在算子间传输形式有两种:one-to-one模式和redistributing模式。one-to-one模式下,流(如source与map算子间)保持分区和元素顺序,map、filter、flatMap等算子间为顺序对应关系,类似于Spark窄依赖。redistributing模式下,分区会改变,根据选择的transform操作,数据被发送至不同目标任务,如keyBy()基于hashCode重分区,broadcast和rebalance随机重新分区,引发redistribute过程,类似于Spark中的shuffle过程,为宽依赖。

       若未设置并行度,系统默认使用flink-conf.yaml配置,值为1。亦可自行设定并行度,代码如下。

flink 并行度

       Flink 作为一套分布式执行框架,计算资源可以不断的扩展。

        不同的任务类型,可以控制需要的计算资源。在flink整个runtime的模型中

        并行度是一个很重要的概念,通过设置并行度可以为认为分配合理的计算资源,

        做到资源的合理配置。

        整个flink的架构简单的说是 中心控制(jobManager)+ 多点分布执行(taskManager)

        弹性的资源分配主要来自于taskManager的有效管理和配置。

        在启动flink 之前,在核心的配置文件里面,需要指定两个参数。

        taskmanager.numberOfTaskSlots 和 parallelism.default。

        首先需要明白slot的概念。对于 taskManager,他其实是一个 JVM 程序。

        这个JVM 可以同时执行多个task,每个task 需要使用本机的硬件资源。

        slot 的属于 jvm 管理的 一些列资源卡槽。 每个slot 只能执行一个task。

        每个slot分配有固定的内存资源,但是不做cpu的隔离。 JVM管理一个 slot的pool,

        用来执行相应的task。taskmanager.numberOfTaskSlots = ,则理论上可以同时执行个子任务。

        那么对于1个5节点,numberOfTaskSlots= 6的集群来说,那么就有个slot可以使用。

        对于具体的一个job来说,他会贪婪的使用所有的 slot吗?

        使用多少slot 是由parallelism.default 决定的。如果是 5, 那么对于一个job 他最多同时使用5个slot。

        这个配置对于多job平台的集群是很有必要的。

        那么给定一个stream api 编写的flink 程序,被分解的task是否和map 到slot 上执行的呢?

        flink 有几个经典的graph, stream-api对应的stream_graph-> job_graph->execution_graph->物理执行图。

        execution_graph 基本就决定了如何分布执行。

        我们知道一个 stream-api, 主要有 source, operate, sink 这几部分。那么我们可以从source开始看 并行的控制。

        source 有并行source和 非并行。我们主要看并行,想类似与kafka 这种生成消费者模式的数据源,能够 并行消费source是非常重要的。

        所以可以看到kafka,FlinkKafkaConsumerBase<T> extends RichParallelSourceFunction<T>,可以充分利用并行度,大大提高吞吐量。

        对应到具体的物理执行上,就是多个 source task 任务执行,他们属于一个kafka group同时消费 不同的partition。

        对于parallelSource,默认使用cpu 核心做并行度。我们可以通过api进行设置。

        接下来是 operate,每个operate都可以设置parallel,如果没有设置将会使用其他层次的设置,比如env,flink.conf中的配置,parallelism.default。

        比如 source. map1().map2().grouby(key).sink()

        这样一个程序,默认,source和 map1,map2有同样的parallel,上游的output 可以直接one-one forwarding.

        在flink 的 优化中,甚至可以把这些 one-one 的operate 合成一个,避免转发,线程切换,网络通信开销。

        对于groupby 这样的算子,则属于另外的一类。上游的output 需要 partion 到下游的不同的节点,而不能做位一个chain。

        由于operate可以设置独自的parallel,如果与上游不一致。上游的output必然需要某种partion策略来 rebalnce数据。kafka有很多策略来处理这个细节。

        对于partion放在专门的章节来说明。

        对于sink,则可以理解位一个特定的operate,目前看没什么特殊处理逻辑。

Flink原理

       Flink架构由JobManager、TaskManager、Client三部分构成。JobManager负责调度、协调checkpoint、故障恢复及状态收集,TaskManager执行计算任务并管理节点服务,而Client用于提交Flink程序,通过建立连接向JobManager提交任务。

       Flink在Yarn环境下的执行流程为:Flink程序通过Client提交至JobManager,JobManager分发至TaskManager执行计算任务。JobManager负责任务调度,管理资源分配,而TaskManager执行计算任务并汇报节点状态。

       Flink的Streaming Dataflow包含数据流模型与多种Operator传递模式,如One to One模式与Redistributing模式。优化操作形成Operator Chain,此链在TaskManager独立线程中执行。

       每个TaskManager是一个JVM进程,包含多个TaskSlot,为并发处理任务提供资源。TaskSlot共享机制在多个任务间动态分配资源,提高资源使用效率。

       Flink的执行流程图由四层构成:StreamGraph、JobGraph、ExecutionGraph、物理执行图。StreamGraph为原始图,JobGraph为优化后的结构,ExecutionGraph为并行化规划,物理执行图则将并行计划落实至具体任务执行。

copyright © 2016 powered by 皮皮网   sitemap