Flink任务提交后,Client向HDFS上传Flink的Jar包和配置,以后向Yarn ResourceManager提交任务,ResourceManager分配Container资源并通知对应的NodeManager启动ApplicationMaster,ApplicationMaster启动后加载Flink的Jar包和配置构建环境,而后启动JobManager,以后ApplicationMaster向ResourceManager申请资源启动TaskManager,ResourceManager分配Container资源后,由ApplicationMaster通知资源所在节点的NodeManager启动TaskManager,NodeManager加载Flink的Jar包和配置构建环境并启动TaskManager,TaskManager启动后向JobManager发送心跳包,并等待JobManager向其分配任务。redis
客户端不是运行时和程序执行的一部分,但它用于准备并发送dataflow给Master,而后,客户端断开链接或者维持链接以等待接收计算结果,客户端能够以两种方式运行:要么做为Java/Scala程序的一部分被程序触发执行,要么以命令行./bin/flink run的方式执行。编程
每个worker(TaskManager)是一个JVM进程,它可能会在独立的线程上执行一个或多个subtask。为了控制一个worker能接收多少个task,worker经过task slot来进行控制(一个worker至少有一个task slot)。·缓存
每一个task slot表示TaskManager拥有资源的一个固定大小的子集。假如一个TaskManager有三个slot,那么它会将其管理的内存分红三份给各个slot。资源slot化意味着一个subtask将不须要跟来自其余job的subtask竞争被管理的内存,取而代之的是它将拥有必定数量的内存储备。须要注意的是,这里不会涉及到CPU的隔离,slot目前仅仅用来隔离task的受管理的内存。数据结构
经过调整task slot的数量,容许用户定义subtask之间如何互相隔离。若是一个TaskManager一个slot,那将意味着每一个task group运行在独立的JVM中(该JVM多是经过一个特定的容器启动的),而一个TaskManager多个slot意味着更多的subtask能够共享同一个JVM。而在同一个JVM进程中的task将共享TCP链接(基于多路复用)和心跳消息。它们也可能共享数据集和数据结构,所以这减小了每一个task的负载。 并发
Task Slot是静态的概念,是指TaskManager具备的并发执行能力,能够经过参数taskmanager.numberOfTaskSlots进行配置,而并行度parallelism是动态概念,即TaskManager运行程序时实际使用的并发能力,能够经过参数parallelism.default进行配置。分布式
也就是说,假设一共有3个TaskManager,每个TaskManager中的分配3个TaskSlot,也就是每一个TaskManager能够接收3个task,一共9个TaskSlot,若是咱们设置parallelism.default=1,即运行程序默认的并行度为1,9个TaskSlot只用了1个,有8个空闲,所以,设置合适的并行度才能提升效率。优化
Flink程序的基础构建模块是 流(streams) 与 转换(transformations)(须要注意的是,Flink的DataSet API所使用的DataSets其内部也是stream)。一个stream能够当作一个中间结果,而一个transformations是以一个或多个stream做为输入的某种operation,该operation利用这些stream进行计算从而产生一个或多个result stream。命令行
在运行时,Flink上运行的程序会被映射成streaming dataflows,它包含了streams和transformations operators。每个dataflow以一个或多个sources开始以一个或多个sinks结束。dataflow相似于任意的有向无环图(DAG),固然特定形式的环能够经过iteration构建。在大部分状况下,程序中的transformations跟dataflow中的operator是一一对应的关系,但有时候,一个transformation可能对应多个operator。线程
Flink程序的执行具备并行、分布式的特性。在执行过程当中,一个 stream 包含一个或多个 stream partition ,而每个 operator 包含一个或多个 operator subtask,这些operator subtasks在不一样的线程、不一样的物理机或不一样的容器中彼此互不依赖得执行。orm
一个特定operator的subtask的个数被称之为其parallelism(并行度)。一个stream的并行度老是等同于其producing operator的并行度。一个程序中,不一样的operator可能具备不一样的并行度。
Stream在operator之间传输数据的形式能够是one-to-one(forwarding)的模式也能够是redistributing的模式,具体是哪种形式,取决于operator的种类。
One-to-one:stream(好比在source和map operator之间)维护着分区以及元素的顺序。那意味着map operator的subtask看到的元素的个数以及顺序跟source operator的subtask生产的元素的个数、顺序相同,map、fliter、flatMap等算子都是one-to-one的对应关系。
Redistributing:stream(map()跟keyBy/window之间或者keyBy/window跟sink之间)的分区会发生改变。每个operator subtask依据所选择的transformation发送数据到不一样的目标subtask。例如,keyBy() 基于hashCode重分区、broadcast和rebalance会随机从新分区,这些算子都会引发redistribute过程,而redistribute过程就相似于Spark中的shuffle过程。
出于分布式执行的目的,Flink将operator的subtask连接在一块儿造成task,每一个task在一个线程中执行。将operators连接成task是很是有效的优化:它能减小线程之间的切换和基于缓存区的数据交换,在减小时延的同时提高吞吐量。连接的行为能够在编程API中进行指定。
下面这幅图,展现了5个subtask以5个并行的线程来执行: