Flink分布式架构与核心组件
Flink作业提交过程
standalone模式下的作业提交过程如下:
在一个作业提交前,Master和TaskManager等进程需要先被启动。我们可以在Flink主目录中执行脚本来启动这些进程
bin/start-cluster.sh
Master和TaskManager被启动后,TaskManager需要将自己注册给Master中的ResourceManager,这个初始化和资源注册过程发生在单个作业提交前,称之为第0步。
①、用户编写应用程序代码,并使用Flink客户端(Client)提交该作业,通常,这些程序会使用java或者Scala语言编写。并调用Flink API构建出逻辑视图,这些代码以及相关配置文件被编译并打包,然后被提交至Master节点的Dispatcher,形成一个应用作业(Application)
②、Dispatcher接收到提交的作业后,会启动一个JobManager,该Jobmanager负责协调这个作业的各项任务。
③、JobManager向ResourceManager申请所需的作业资源,这些资源可能包括cpu,内存等。
④、由于在前面的步骤中,TaskManager已经向ResourceManager注册了可供使用的资源,这时处于空闲状态的TaskManager将被分配给JobManager。
⑤、JobManager将用户作业中的逻辑视图转化为物理视图,如上面的视图中,该图显示了作业被并行化后的执行过程,JobManager将计算任务分配并部署到多个TaskManager上,此时,一个Flink作业正式开始执行。
在计算任务执行过程中,TaskManager可能会与其他TaskManager交换数据,使用特定的数据交换策略。同时,TaskManager还会将任务的状态信息传递给JobManager,这些状态信息包括任务的启动,执行和终止状态,以及快照的元数据等。
Flink的核心组件
在这个作业提交流程的基础上,进一步介绍下各个组件
①、Client:客户端,用户通常使用Flink提供的客户端工具(如位于Flink主目录下的bin目录中的命令行工具)来提交作业,客户端会对用户提交的Flink作业进行预处理,并将作业提交到Flink集群中。在提交作业时,客户端需要配置一些必要的参数。例如使用Standalone集群还是YARN集群等。整个作业会被打包成一个JAR文件,DataStream API会被转换成一个JobGraph,该图类似于逻辑视图。
②、Dispatcher(调度器):Dispatcher可以接收多个作业,每次接收作业时,会为该作业分配一个JobManager,Dispatcher通过提供表述性状态转移REST式的接口,使用超文本传输协议HTTP来对外提供服务。
③、JobManager(作业管理器):JobManager是单个Flink作业的协调者。每个作业都有一个对应的JobManager负责管理。JobManager将客户端提交的JobGraph转换为ExecutionGraph,该图类似于并行物理执行图,JobManager会向ResourceManager申请所需的资源。一旦获取足够的资源,JobManager会将ExecutionGraph及其他计算任务分发到多个TaskManager上。此外,JobManager还管理多个TaskManager,包括收集作业状态信息,生成检查点,必要时进行故障恢复等。
④、ResourceManager(资源管理器):Flink可以在Standalone,YARN,kubernetes等环境中部署,而不同环境对计算资源的管理模式有所不同,为了解决资源分配问题,Flink引入了ResourceManager模块,在Flink中,计算资源的基本单位是TaskManafger上的任务槽位Slot,ResourceManager的主要职责是从资源提供方(如YARN)获取计算资源,当JobManager需要计算资源时,ResourceManager会将空闲的Slot分配给JobManager,在计算任务结束后,ResourceManager会回收这些空闲的Slot。
⑤、TaskManager(任务管理器):TaskManager是实际执行计算任务的节点,一般来说,一个Flink作业会分布在多个TaskManager上执行,每个TaskManager提供一定数量的Slot,当一个TaskManager启动后,相关的Slot信息会被注册到ResourceManager中。当Flink作业提交后,ResourceManager会将空闲的Slot分配给JobManager,一旦JobManager获取了空闲的Slot,它会将具体的计算任务部署到这些Slot,并在这些Slot上执行。在执行的过程中,TaskManager可能会与其他的TaskManager进行数据交换,因此需要进行必要的数据通信,总之,TaskManager负责具体的计算任务的执行,它会在启动时将Slot资源向ResourceManager注册。
Flink组件栈
①、部署层
Local模式:Flink支持本地模式,包括单节点(SingleNode)和单虚拟机(SingleJVM)模式,在SingleNode模式中,JobManager和TaskManger运行在同一个节点上;在SingleJVM模式中,所有的角色都在同一个JVM上运行。
Cluster模式:Flink可以部署在Standalone,YARN,Mesos和Kubernetes集群上,Standalone集群需要配置JobManager和TaskManager的节点,然后通过Flink提供的脚本启动。YARN,Mesos和Kubernetes集群提供了更强大的资源管理和集群扩展能力。
Cloud模式:FlinK还可以部署在各大运平台上,如AWS,谷歌云和阿里云,使用户能够在云环境中灵活地部署和运行作业。
②、运行时层
运行时层是Flink的核心组件,支持分布式执行和处理,该层负责将用户提交的作业转换为任务,并分发到相应的JobManager和TaskManager上执行,运行时层还涵盖了检查点和故障恢复机制,确保作业的容错性和稳定性。
③、API层
Flink的API层提供了DataStream API 和DataSet API,分别用于流式处理和批处理,这两个API允许开发者使用各种操作符和转换来处理数据,包括转换,连接,聚合,窗口等计算任务。
④、上层工具
在API层之上,Flink还提供了一些工具来扩展其功能:
a:复杂事件处理(CEP):面向流处理的库,用于检测和处理复杂的事件模式。
b:图计算库(Gelly):面向批处理的图计算库,用于执行图算法。
c:Table API和SQL:针对SQL用户和关系型数据处理场景的接口,允许用户使用SQL语法和表处理流和批数据。
d:PyFlink:针对Python用户的接口,使其能够使用Flink进行数据处理,目前主要基于Table API.
综上所述,Flink可以在不同层次上提供了丰富的组件和工具,支持流处理和批处理,以及与不同环境(本地,集群,云)的无缝集成,使开发者能够灵活地构建和部署大规模数据处理应用程序。
作业执行阶段
在Apache Flink中,数据流作业的执行过程可以划分为多个阶段,从逻辑视图到物理执行图的转换,这个过程包括了从StreamGraph到JobGraph,再到ExecutionGraph,最终映射到实际的物理执行图,下面详细说明这个过程:
a:StreamGraph:逻辑视图:StreamGraph是用户编写的流处理应用程序的逻辑表示。它包含了流的转换操作,算子之间的关系,事件时间处理策略,容错配置等。StreamGraph是用户定义的数据流拓扑,是一种高级抽象,用户可以通过DataStram API构建StreamGraph。
b:JobGraph作业图:JobGraph是从StreamGraph派生而来的,表示一个具体的作业执行计划,在JobGraph中,StreamGraph中的逻辑算子被映为具体的物理算子,且有明确的执行顺序和任务间的依赖关系。JobGraph还包含了资源配置,任务并行度,优化选项等信息,JobGraph是从逻辑视图转换物理执行的关键步骤。
c:ExecutionGraph(执行图):ExecutionGraph是JobGraph的执行时表示,它是实际执行计划的核心,在ExecutionGraph中,JobGraph中的每个任务都会被映射到一个具体的执行任务,每个任务可以包含一个或者多个子任务,这些子任务被映射到不同的TaskManager上,ExecutionGraph还负责维护作业的执行的状态,以及任务之间的调度和通信。
d:物理执行图:ExecutionGraph被映射到实际的物理执行图,即在TaskManager集群上真正执行的任务拓扑,物理执行图包括了任务的并行执行,数据交换,任务状态管理等细节,它是作业分布式环境中实际运行的体现。
总结起来,StreamGraph到JobGraph到ExecutionGraph的转换是Flink作业执行计算的关键步骤。从逻辑视图到物理执行图的转换过程考虑了作业的拓扑结构,资源分配,任务调度等方面的问题,确保了作业可以在分布式环境中高效的运行,这一系列转换过程使得用户可以通过高层次的抽象来描述作业的逻辑,而Flink框架会负责将其转换为可以执行的任务图,实现数据流的处理和计算。