1. 基本概念
运行 Flink 应用其实非常简单,但是在运行 Flink 应用之前,还是有必要了解 Flink 运行时的各个 组件,因为这涉及到 Flink 应用的配置问题。
通过这张图我们可以看到,在一个 DAG 图中,不能被 chain 在一起operator 会被分隔到不同的 Task 中,也就是说,Task 是 Flink 中资源调度的最小单位。
Flink 运行时包括两类进程:
● JobManager(又称为 JobMaster):协调 Task 的分布式执行,包括调度 Task、协调创建checkpoint 以及当 job failover 时协调各个 Task checkpoint 恢复等。
● TaskManager(又称为 Worker):执行 dataflow 中的 Tasks,包括内存 buffer 的分配、Data Stream 的传递等。
Worker与Slots
worker
每一个worker(TaskManager)是一个JVM进程,它可能会在独立的线程上执行一个或多个subtask。
slots
为了控制一个worker能接收多少个task,worker通过task slot来进行控制(一个worker至少有一个task slot)。每个task slot表示TaskManager拥有资源的一个固定大小的子集。假如一个TaskManager有三个slot,那么它会将其管理的内存分成三份给各个slot。资源slot化意味着一个subtask将不需要跟来自其他job的subtask竞争被管理的内存,取而代之的是它将拥有一定数量的内存储备。需要注意的是,这里不会涉及到CPU的隔离,slot目前仅仅用来隔离task的受管理的内存。
通过调整task slot的数量,允许用户定义subtask之间如何互相隔离。如果一个TaskManager一个slot,那将意味着每个task group运行在独立的JVM中,而一个TaskManager多个slot意味着更多的subtask可以共享同一个JVM。而在同一个JVM进程中的task将共享TCP连接(基于多路复用)和心跳消息。它们也可能共享数据集和数据结构,因此这减少了每个task的负载。
Task Slot是静态的概念,是指TaskManager具有的并发执行能力,可以通过参数taskmanager.numberOfTaskSlots进行配置.并行度parallelism是动态概念,即TaskManager运行程序时实际使用的并发能力,可以通过参数parallelism.default进行配置。
也就是说,假设一共有3个TaskManager,每一个TaskManager中的分配3个TaskSlot,也就是每个TaskManager可以接收3个task,一共9个TaskSlot,如果我们设置parallelism.default=1,即运行程序默认的并行度为1,9个TaskSlot只用了1个,有8个空闲,因此,设置合适的并行度才能提高效率。Flink的每个TaskManager为集群提供solt。 solt的数量通常与每个TaskManager节点的可用CPU内核数成比例。一般情况下你的slot数是你每个节点的cpu的核数。
并行度(Parallel)
一个Flink程序由多个任务组成(source、transformation和 sink)。 一个任务由多个并行的实例(线程)来执行, 一个任务的并行实例(线程)数目就被称为该任务的并行度。
任务的并行度设置可以从多个层次指定
•Operator Level(算子层次)
•Execution Environment Level(执行环境层次)
•Client Level(客户端层次)
•System Level(系统层次)
1.并行度设置之Operator Level
算子、数据源和sink的并行度可以通过调用 setParallelism()方法来指定
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> text = [...]
DataStream<Tuple2<String, Integer>> wordCounts = text
.flatMap(new LineSplitter())
.keyBy(0)
.timeWindow(Time.seconds(5))
.sum(1).setParallelism(5);
wordCounts.print();
env.execute("Word Count Example");
2.并行度设置之Execution Environment Level
执行环境(任务)的默认并行度可以通过调用setParallelism()方法指定。为了以并行度3来执行所有的算子、数据源和data sink, 可以通过如下的方式设置执行环境的并行度:
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(3);
DataStream<String> text = [...]
DataStream<Tuple2<String, Integer>> wordCounts = [...]
wordCounts.print();
env.execute("Word Count Example");
3.并行度设置之Client Level
并行度可以在客户端将job提交到Flink时设定。对于CLI客户端,可以通过-p参数指定并行度:
./bin/flink run -p 10 ../examples/*WordCount-java*.jar
4.并行度设置之System Level
在系统级可以通过设置flink-conf.yaml文件中的parallelism.default属性来指定所有执行环境的默认并行度
并行度设置的优先级
设置最大并发度
最大并发度可以在你设置并发度的地方设置(除开客户端级别和系统级别外),你可以通过调用setMaxParallelism()方法来设置最大并发度。
默认的最大并发度大致为operatorParallelism + (parallelism/2) ,其中下限为127,上限为32768