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,是没有经过任何优化的时候,可以看到包含4Operator/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不同TaskSubtask运行在一个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等编程语言