Flink 为什么使用的slot数量比task少? task subtask slot 是什么样的关系呢?

Flink 为什么使用的slot数量比task少? task subtask slot 是什么样的关系呢?

  • 前言
  • TaskManager 和 JobManager
  • Task Slots
  • Task 和 subtask
  • 如何计算有task和subtask数量
    • FIink 算子连接模式
  • Operator Chains
    • SlotSharingGroup


前言

最近在部署flink集群,遇到了一些问题,觉得是蛮有意思的事情,所有就写点材料,和有需要的朋友交流分享一下。本来我只是为了解决问题,现在既然写点材料的话为了专业性,所以我特地去官网查看了部分词汇,有需要的兄弟直接链接送上。词汇表


TaskManager 和 JobManager

flink集群有jobmanager和flinkmanager

  • jobManager 是 Flink 集群的主节点。
    jobmanager用于分配任务,自己不执行任务,一般只有一个。高可用可能有多个 ,其中一个始终是 leader,其他的则是 standby
  • taskManager 是 Flink 集群 的工作进程
    taskmanager有多个,用于执行任务。

领导一般只有一个,只管天马行空想需求,下面开发团队有一堆,熬夜实现领导的天马行空。

Task Slots

  • Task Slots 每个 TaskManager都是一个 JVM 进程,可以在单独的线程中执行一个或多个 subtask。为了控制一个 TaskManager 中接受多少个 task,就有了所谓的 task slots。
    一个taskmanager可以配置多个slot,平分资源。也就是一个团队可以招多个人,但是总共就那么多钱。不过还是不太一样,毕竟你旁边的同事可能工资比你高事情比你少。在这里可能事情也是不一样多,但工资还是一样的,比较公平。

Task 和 subtask

  • task 是工作的基本单元
    下图就表示有6个task
    Flink 为什么使用的slot数量比task少? task subtask slot 是什么样的关系呢?_第1张图片

  • subTask task 的每一个分区会形成一个 subTask
    其实有多少个并行度就会有多少个分区,如上图看到的每个并行度都是40,我随意点开一个可以看到有40个subtask
    Flink 为什么使用的slot数量比task少? task subtask slot 是什么样的关系呢?_第2张图片

如何计算有task和subtask数量

以wordcount为例

	//源
	DataStream<String> inputDataStream = env.addSource(...).setParallelism(2);//并行度2
	//转换
	DataStream<Event> flatStream = inputDataStream.flatMap(...).setParallelism(2);//并行度2
	//分组 开窗 聚合
	DataStream<statistic> resultStream = flatStream.keyBy ("id").timeWindow (..).apply(..).setParallelism(2);//并行度2
	//输出
	resultStream.addSink(...).setParallelism(1);//并行度1

网上找了个DAG图,代码根据图改的。
Flink 为什么使用的slot数量比task少? task subtask slot 是什么样的关系呢?_第3张图片
图中 source/map 的并行度都是 2,keyby/window/apply 的并行度也都是 2,sink 的是 1

FIink 算子连接模式

补充一下上FIink 算子连接模式的概念,上下游算子通过数据流进行连接,有两种模式。

  • One-to-one :保留元素的分区和排序。这意味上下游运算符将获取到相同顺序元素。
    需要满足没有洗牌,且并行度一样。不满足其中一项就不属于One-to-one

  • Redistributing :更改流的分区。每个运算符都将数据发送到不同的目标子任务,具体取决于所选的转换。比如 keyBy()(其重新分区通过散列键),broadcast(), or rebalance()(其重新分区随机地)。在重新分配交换中,元素之间的顺序仅保留在每对发送和接收子任务中。

因此 source 到 map 属于 One-to-one 的模式,所有 source 和 map 划分成一个 task,后面的 map 到 keyBy ,和最后的 sink 都有 洗牌 产生,并行度发生改变,所以 keyBy,sink 都是一个单独的 task。
因此共有 3 个task,其中 source,map 并行度是 2,所以有两个 subTask,以此类推共有 5 个 subtask

Operator Chains

算子链由两个或多个连续的 Operator 组成,两者之间没有任何的洗牌。同一算子链内的算子可以彼此直接传递 record,而无需通过序列化或 Flink 的网络栈。它减少线程间切换、缓冲的开销,并且减少延迟的同时增加整体吞吐量,链行为是可以配置的;

经典的 WordCount 为例,下面这幅图,展示了 Source 并行度为 1,FlatMap、KeyAggregation、Sink并行度均为 2,最终以 5 个并行的线程来执行的优化过程
Flink 为什么使用的slot数量比task少? task subtask slot 是什么样的关系呢?_第4张图片
上图中将 KeyAggregation 和 Sink 两个 operator 进行了合并,因为这两个合并后并不会改变整体的拓扑结构。
注意 正是因为这样的优化,一个slot就有可能包含多个task。就出现了我遇到的情况,40个task只用10个槽。
Flink 为什么使用的slot数量比task少? task subtask slot 是什么样的关系呢?_第5张图片

SlotSharingGroup

有时了防止同一个 slot 包含太多的 task,或者我们希望把计算逻辑复杂的算子单独使用 slot ,提高计算速度,Flink 提供了资源组的概念。group 就是对 算子 进行分组,同一 组 的不同 算子 task 可以共享同一个 slot。
默认所有 operator 属于同一个组"default",可以通过 slotSharingGroup() 为不同的 operator 设置不同的group。

.slotSharingGroup(SINK_GROUP_NAME);

你可能感兴趣的:(flink,flink,java,大数据)