Flink概述
what:
flink的整体架构,如下:
Flink运行时涉及到的进程主要有以下两个:jobManager和taskManager。
jobManager:
职责:主要负责task协调,和checkPoint的错误恢复等。
具体方式:当客户端将打包好的任务提交到JobManager之后,JobManager就会根据注册的TaskManager资源信息,将任务分配给有资源的TaskManager,然后启动运行任务。TaskManger从JobManager获取task信息,然后使用slot资源运行task。
TaskManager:
职责:执行数据流的task,一个task通过设置并行度,可能会有多个subtask
具体方式:每个TaskManager都是作为一个独立的JVM进程运行的。他主要负责在独立的线程执行的operator。其中能执行多少个operator取决于每个taskManager指定的slots数量。Task slot是Flink中最小的资源单位。假如一个taskManager有3个slot,他就会给每个slot分配1/3的内存资源,目前slot不会对cpu进行隔离。同一个taskManager中的slot会共享网络资源和心跳信息。
在某些情况下,一个slot中也可能执行多个task。一般情况下,flink都是默认允许共用slot的,即便不是相同的task,只要都是来同一个job即可。
job & task & subtask:
job:一个Job代表一个可以独立提交的大任务,可以认为一个execute
或者executeAsync
就产生一个Job,我们向JobManager提交任务的时候就是以Job为单位的,只不过一份代码里面可以包含多个Job。
Task和Subtask,如下图:
a、每个圆代表一个Operator,每个虚线圆角框代表一个Task,每个虚线方框代表一个Subtask,其中的p表示并行度。
b、最上面是StreamGraph,是没有经过任何优化的时候,可以看到包含4个Operator/Task:Task A1、Task A2、Task B、Task C。
c、StreamGraph经过Operator Chain之后,Task A1和Task A2两个Task合并成了一个新的Task A(同时也可以认为合并产生了一个新的Operator),得到了中间的JobGraph。
d、以并行度为2(需要2个slot)执行的时候,Task A产生了2个Subtask,分别占用了Thread #1和Thread #2两个线程;Task B产生了2个Subtask,分别占用了Thread #3和Thread #3两个线程;Task C产生了1个Subtask,占用了Thread5。
总结:1、Task是逻辑概念,一个Operator就代表一个Task(多个Operator被chain之后产生的新Operator算一个Operator);
2、正运行的时候,Task会按照并行度分成多个Subtask,Subtask是执行/调度的基本单元;
3、每个Subtask需要一个线程来执行;
评估“一个应用大概会产生多少个线程”:
根据JobGraph计算,所有Operator和它的并行度的乘积,如下:
slot sharing:
TaskManager是真正干活的,启动的时候会将自己的资源以Slot的方式注册到ResourceManager,然后JobMaster从ResourceManager处申请到Slot资源之后将自己优化过后的任务调度到这些Slot上面去运行,在整个过程中Subtask是调度的基本单元,Slot则是资源分配的基本单元。需要注意的是目前Slot只隔离内存,不隔离CPU。
Flink默认允许同一个Job中不同Task的Subtask运行在一个Slot中,这就是SlotSharing。详解如下:
a、必须是同一个Job。slot是给Job分配的资源,目的:就是隔离各个Job,如果跨Job共享,但隔离就失效了;
b、必须是不同Task的Subtask。这样是为了更好的资源均衡和利用。一个计算流中(pipeline),每个Subtask的资源消耗肯定是不一样的,如果都均分slot,那必然有些资源利用率高,有些低。限制不同Task的Subtask共享可以尽量让资源占用高的和资源占用低的放一起,而不是把多个高的或多个低的放一起。比如一个计算流中,source和sink一般都是IO操作,特别是source,一般都是网络读,相比于中间的计算Operator,资源消耗并不大;
c、默认是允许sharing的,也就是你也可以关闭这个特性;
6个Slot,5个Subtask,并行度为2。此时Subtask少于Slot个数,所以每个Subtask独占一个Slot,没有SlotSharing。运行分配的情况,如下官方的图:
6个Slot,5个Subtask,并行度为6。Subtask的个数多于Slot了,所以出现了SlotSharing,一个Slot中分配了多个Subtask(下图中:特别是最左边的Slot中跑了一个完整的Pipeline)。运行分配的情况,如下官方的图:
slot sharing具体好处:
1、提高了资源利用率(上面讲过);
2、简化了并行度和Slot之间的关系:一个Job运行需要的Slot个数就是其中并行度最高的那个Task的并行度。
编程结构:
这4层中,一般用于开发的是第三层,即DataStrem/DataSetAPI
。用户可以使用DataStream API
处理无界数据流,使用DataSet API
处理有界数据流。同时这两个API都提供了各种各样的接口来处理数据。例如常见的map、filter、flatMap等等,而且支持python,scala,java等编程语言