Flink相关学习

尚硅谷网课

Posted by Haiming on January 19, 2021

012 尚硅谷 Flink理论 Flink运行架构(二)Slot和并行度

到底什么是slot?和taskManager又有什么关系?

https://ci.apache.org/projects/flink/flink-docs-release-1.10/zh/concepts/runtime.html#task-slots-%E5%92%8C%E8%B5%84%E6%BA%90

TaskManagers with shared Task Slots

Slot是TaskManager为了将资源做划分,从而提高并行度的一种措施。Slot主要是对内存和网络进行了划分,而没有对于CPU的资源进行划分。

一个TaskManager就是一个JVM进程,其会在多个独立的线程上面执行对应的subTask。

JVM内部的线程不是共用资源吗?为什么这里的每一个slot是一个线程,但是其资源是划分开的?

下面是我自己的理解:

正常来说,一个多线程的进程,执行的任务是高度相似的,比如我们使用线程池做一些批量处理的任务。但是在TaskManager里面则不是这样,往往一个JVM进程之中所执行的是已经转换好的任务执行图的多个不同的部分,为了避免任务之间彼此抢占资源(因为其根本就不需要共享,阶段都不同),从而将整体的资源分成几个slot进行处理。

TaskManager允许在一个slot之中并行的执行子任务,比如上面的这个图,每一个slot之中都有并行的子任务在进行处理。可能在一个执行图之中,有的任务需要的资源多,有的任务需要的资源少,那么相对而言这种综合分配可以达到最大的资源利用效率。

允许slot共享的好处:

  1. 将对资源占用多和对资源占用少的任务进行综合调配,不会出现如果均摊任务(每一个子任务占用一个slot)的情况下导致的忙的忙死,闲的等任务的情况
  2. 在JobManager分配slot的时候,不需要将所有阶段的subTask加起来,而是可以直接将并行度最高的subTask当做任务分配时候的参数。
  3. 一个slot里面就可以保存整个data processing pipeline,相当于任务切片

我就想相同类型的子任务放在一个slot里面,能不能?

当然能。只要设置好sharingGroup就可以。默认是所有的任务在一个sharingGroup之中,所以会按照资源的均衡方面进行分配。如果想一样的subTask放在一个slot之中,将相同的任务设置在相同的sharingGroup即可。

014 尚硅谷 Flink理论 Flink运行架构(四)任务调度控制

  1. 调用链的好处?

调用链(Operator chain)可以让本来需要通信和序列化/反序列化的任务之间的操作直接变成本地内存之中的方法调用,大大减少了所需要的时间。

  1. 有的时候某些任务的复杂度太高,我不想让他们自动形成调用链,那么我该怎么办?

有的时候某些任务的耗时长,消耗资源大,这个时候我们不想让其自动形成调用链,而是想横向扩展提高并行度从而提高整个系统的吞吐量,这个时候就需要我们将其指定好对应的组,不让系统进行自动的分配调用链。

env.disableOperatorChaining()

当然在方法的层面也是可以做到的,有两种不同的使用方式:

  1. 想要将某一个subtask进行单独的隔离(前后都拆开),那么这种情况下使用disableChaining()
  2. 想要将某个subtask只和前面拆开,而和后面做一起的聚合,这种情况下使用startNewChain()

015 尚硅谷 Flink理论 Flink DataStream API(一)环境和简单source

  1. Flink的job大致分为几部分?

四部分:

  1. 创建执行环境
  2. source
  3. transform
  4. sink

其中2,3,4是我们之前提到过的任务的主体。

  1. 如果我想创建执行环境,有几种做法?什么关系?

主要有三种:

  1. getExecutionEnvironment
  2. createLocalEnvironment
  3. createRemoteEnvironment

第二种和第三种比第一种更底层,比如Remote的那个还要指定对应集群的IP和端口。

为什么一般不用第二和第三种?假设是这样使用,那么在本地测试时候使用Local的方法,而在提交的时候使用的是Remote的那个方法,意味着需要将代码部分进行改动。这是很危险的事情。

  1. 如何避免kafka的重复消费(job在处理途中如果挂掉怎么回滚)

其实对于kafka,主要是操作offset。在Spark之中有两种方式:

  1. 在一批数据确认处理完再修改offset
  2. 在落盘checkpoint的时候,也将这一批的对应数据进行落盘,在恢复job的时候操作offset进行处理。

而对于flink而言,因为其本身就是有状态的操作,所以在记录状态的时候就可以将kafka对应的offset当做状态之中的某一项进行记录,这样恢复的时候也可以进行恢复。所以对于Flink而言,exactly-once的实现可以自动实现,本身什么都不需要做。自动实现状态一致性。