Flink parallelism和Slot介绍

什么是parallelism?

        一个Flink程序是由多个任务组成(source、transformation和sink)。一个任务由多个并行的实例(线程)来执行,一个任务的并行实例(线程)数目就被称为该任务的并行度。

        并行的意思,在Flink中代表每个任务的并行度,适当的提高并行度可以大大提高job的执行效率,比如当你的job消费kafka的速度过慢,适当调大就消费正常了。在flink配置文件中可以看到其默认并行度是1。

如何设置并行度?

  • 命令行:./bin/flink run -p 10 ../wordcount.jar
  • 代码中:env.setParallelism(10)

这里设置的并行度,是整个程序的并行度,那么如果后面的每个算子不单独设置并行度覆盖的话,那么后面每个算子的并行度都是这里设置的值了。flink允许用户在每个算子后面给每个具体算子单独设置并行度:

data.keyBy(new xxxKey())
    .flatMap(new XxxFlatMapFunction()).setParallelism(5)
    .map(new XxxMapFunction).setParallelism(5)
    .addSink(new XxxSink()).setParallelism(1)

任务的并行度可以从多个层次指定

优先级由高到低:

  • Operator Level(算子层次)
.flatMap(new XxxFlatMapFunction()).setParallelism(5)
.map(new XxxMapFunction).setParallelism(5)
  • Execution Environment Level(执行环境层次)
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(3);
  • Client Level(客户端层次)
./bin/flink run -p 10 ../examples/*WordCount-java*.jar
  • System Level(系统层次)
    在系统级可以通过设置flink-conf.yaml文件中的parallelism.default属性来指定所有执行环境的默认并行度

operator subtask

        在程序执行期间,一个流会生成一个或者多个stream的partition,并且一个operator会生成一个或者多个operator subtask。operator的subtask彼此之间是独立的,分别在不同的线程里去执行并且可能分布在不同的机器上或者containers上。operator的subtasks的数量等于该操作算子的并行度的数量。流的并行度有总是取决于产生它的操作算子的并行度决定的。同一个flink程序中的不同的operators可能有不同的并行度。

Slot

  1. 每一个Worker(TaskManager)都是一个JVM进程,他可能会在独立的线程中执行一个或者多个subtask。为了控制worker能够接收多个task,worker通过task slot来进行控制(一个worker至少有一个task slot)。
  2. 每个task slot表示TaskManager拥有资源的一个固定大小的子集。假如一个TaskManager有三个slot,那么它会将其管理的内存分成三份给各个slot。slot的资源化意味着一个job的subtask将不需要跟来自其它job的subtask竞争被管理的内存。
  3. 通过调整task slots的数量,用户可以定义subtasks它们之间如何互相隔离。如果一个TaskManager一个slot,那将意味着每个task group独立的运行在JVM中。而一个TaskManager多个slot意味着更多的subtask可以共享一个JVM。而在同一个JVM进程中的task将共享TCP连接和心跳消息。它们也可能共享数据集和数据结构,这样可以减少每个task的负载。

        默认,如果subtask是来自相同的job,但不是相同的task,Flink允许subtask共享slot。这样就会出现一个slot可能容纳一个job中的整个pipeline。允许slot共享有以下两个好处:

  1. Flink集群需要的task slots的数量和作业中的最高并行度的一致。不需要计算一个程序总共包含多少个task。
  2. 更好的利用资源。如果没有slot共享,非密集型source/map()子任务将阻塞与资源密集型窗口子任务一样多的资源;在slot共享的话,将我们上图中的示例的基本并行度从2提高到6,可以充分利用slot资源,同时确保繁重的subtasks在Taskmanager中公平分配。修改并行度后如下图所示:source/map/keyby/window/apply 最大可以有 6 个并行度,sink 只用了 1 个并行。每个 Flink TaskManager 在集群中提供 slot。 slot 的数量通常与每个 TaskManager 的可用 CPU 内核数成比例。一般情况下你的 slot 数是你每个 TaskManager 的 cpu 的核数。

 

注意:这里的job就是一个flink任务,task就是该任务里面的source、map、sink等,而subtask就是每个task的多个并行实例(实例个数就是并行度的大小),如果并行度为2,那么source[1],source[2]就是两个属于source的subtask。

Flink系统架构

       图中 Task Manager 是从 Job Manager 处接收需要部署的 Task,任务的并行性由每个 Task Manager 上可用的 slot 决定。每个任务代表分配给任务槽的一组资源,slot 在 Flink 里面可以认为是资源组,Flink 将每个任务分成子任务并且将这些子任务分配到 slot 来并行执行程序。

       例如,如果 Task Manager 有四个 slot,那么它将为每个 slot 分配 25% 的内存。 可以在一个 slot 中运行一个或多个线程。 同一 slot 中的线程共享相同的 JVM。 同一 JVM 中的任务共享 TCP 连接和心跳消息。Task Manager 的一个 Slot 代表一个可用线程,该线程具有固定的内存,注意 Slot 只对内存隔离,没有对 CPU 隔离。默认情况下,Flink 允许子任务共享 Slot,即使它们是不同 task 的 subtask,只要它们来自相同的 job。这种共享可以有更好的资源利用率。

       上面图片中有两个 Task Manager,每个 Task Manager 有三个 slot,这样我们的算子最大并行度那么就可以达到 6 个,在同一个 slot 里面可以执行 1 至多个子任务。

slot和parallelism

下面给出官方的图片来更加深刻的理解下slot:

1、slot 是指 taskmanager 的并发执行能力

 

taskmanager.numberOfTaskSlots:3

每一个 taskmanager 中的分配 3 个 TaskSlot, 3 个 taskmanager 一共有 9 个 TaskSlot。

2、parallelism 是指 taskmanager 实际使用的并发能力

 

parallelism.default:1

运行程序默认的并行度为1,9个TaskSlot只用了1个,有8个空闲。设置合适并行度才能提高效率。

3、parallelism 是可配置、可指定的

 

上图中 example2 每个算子设置的并行度是 2, example3 每个算子设置的并行度是 9。

 

example4 除了 sink 是设置的并行度为 1,其他算子设置的并行度都是 9。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值