【Flink系列二】如何计算Job并行度及slots数量

接上文的问题

  1. 并行的任务,需要占用多少slot ?
  2. 一个流处理程序,需要包含多少个任务

首先明确一下概念

slot:TM上分配资源的最小单元,它代表的是资源(比如1G内存,而非线程的概念,好多人把slot类比成线程,是不恰当的)

任务(task):线程调度的最小单元,和java中的类似。

---------------------------------------------------------------------------

为更好的去理解后面如何计算并行度及需要的slots数量,先介绍一下几个概念

并行度(Parallelism)

图1

  •  一个特定算子的子任务(subtask)的个数被称之为并行度(parallelism)一般情况下,一个stream的并行度,可以认为就是其所有算子中最大的并行度。
  • 图中source算子的并行度=2,map算子的并行度=2,keyby算子的并行度=2,sink算子的并行度=1

ps:并行度的设置有3个地方,1=代码中指定,2=提交Job时指定-p参数,3=Flink配置文件conf中执行,其优先级1>2>3, 不详细展开,有问题可以评论区

由图1,我们可以算出stream的任务数=7(两个source + 两个map + 两个keyby + 一个sink)

TaskManager和Slots

图2

  • Flink中每个TaskManager都是一个JVM进程,它可能会在独立的线程上执行一个或多个任务
  • 为了控制一个TM(TaskManager缩写)能接受多少哥task,TM通过task slot来进行控制(一个TM至少有1个slot)
  • 建议TM中slot数量设置为cpu核心数,因为一个TM中slot内存的独享的,但是cpu是共享的,为避免不同slot执行任务时争抢cpu资源,建议slot数量设置和cpu核心数一致
  • 图中slot数量决定了TM上的最大线程并行能力,一个slot可以执行一个线程,也可以串行执行多个线程。

图2中我们看到

  1. source和map算子合并到一块了,那为什么可以合并呢?
  2. 合并后每个任务都占用一个slot,一共是占用了5个slot,现实真的是这样的吗?

带着问题,再看一个例子

source和map算子及keyby算子的并行都调整为6,sink算子的并行度还是1,排列方式如图

图3

按照我们上面的理解,我们应该需要的slot数量=6+6+1=13,但是这样会造成slot资源的浪费(流处理任务第一个算子处理完了之后需要等后面的算子都执行完,再开始下一批次的任务处理),为此,Flink允许任务共享slot

  • 默认情况下,Flink允许子任务共享slot(必须是前后执行的不同的任务),及时他们是不同任务的子任务。这样的结果是,一个slot可以保存作业的整个管道。
  • Task slot是静态的概念,是指TM具有的并发的并行执行能力

所以,Flink优化后一共占用6个slot。

slot共享组

  • 任务槽共享的好处:

1.Flink 集群所需的 task slot 和作业中使用的最大并行度恰好一样。无需计算程序总共包含多少个 task(具有不同并行度)。
2.资源 容易获得更好的资源利用。如果没有 slot 共享,非密集 subtask(source/map())将阻塞和密集型 subtask(window)
一样多的资源
 

默认情况下会设置一个默认的共享组, slotSharingGroup("default"),这样所有的算子都可以共享slot;如果想让两个算子任务不共享slot,通过调整共享组来实现。 不同的共享组一定在不同的slot上

// 1. 创建执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(conf);
        //设置并行度,所有算子都默认这个并行度
        env.setParallelism(1);


        DataStreamSource<String> ds = env.socketTextStream("hadoop102", 8888);

        ds.flatmap(new WordCount.MyFlatMapper()).name("f1").setParallelism(2).slotSharingGroup("a")
          .keyBy(0)
          .sum(1).setParallelism(2).slotSharingGroup("c");
          .print().setParallelism(1)

        // 5. 启动执行
        env.execute();

show plan后我们可以看到slot没有共享,执行stream需要4个slot

图4

如果不单独设置slot共享组,那么该任务的slot个数=2,

并行子任务的分配

图5

图5中有两条不同的流,每个字母右下角的下标代表并行度,A并行度=4,B并行度=4,C并行度=2,D并行度=4,E并行度=2;

整个任务开启slot共享后,一个会有4+4+4+2+2=16个任务,一共需要申请4个slot;

C->D过程涉及数据的合并,需要将数据copy到D的每个子任务中。

总结

下图中在flink中配置文件flink-conf设置的并行度是3,flink集群中TM数量=3,每个TM中slot数量=3

Example1中代码中设置的paeallelism=1,并且允许slot共享,所以会占用1个slot,3个算子任务

Example1中代码中设置的paeallelism=2,并且允许slot共享,所以会占用2个slot,6个算子任务

  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周润发的弟弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值