Flink on YARN是如何确定TaskManager个数的
1. 计算公式
先看计算公式:(结果向上取整)
TaskManager个数 = Job的最大并行度 / 每个TaskManager分配的任务槽数
(注意老版本有参数-yn / --yarncontainer 来指定运行的 TaskManager个数,已经失效)
再来看看什么是并行度和任务槽数以及他们是如何确定的。
2. 并行度(parallelism)
一个Flink程序由多个Operator组成(source、transformation和 sink)。
一个Operator由多个并行的Task(线程)来执行, 一个Operator的并行Task(线程)数目就被称为该Operator(任务)的并行度(Parallel)。即并行度就是相对于Operator来说的。
并行度的指定,可以有4种级别来设置Operator的并行度
1) Operator Level(算子级别)
operator.setParallelism(3)
2)Execution Environment Level(执行环境级别)
streamExecutionEnvironment.setParallelism(3)
3)Client Level(客户端级别)
./bin/flink run -p 3 ...
4)System Level(系统默认级别,不推荐,因为会影响所有作业)
即在配置文件flink-conf.yaml中的配置项 parallelism.default
并行度的优先级:算子级别 > env级别 > 客户端级别 > 系统默认级别
3. 任务槽(task slot)
每个worker (TaskManager)是一个JVM进程,可以在单独的线程中执行一个或多个子任务。为了控制TaskManager接受的任务数量,它提出了任务槽的概念。每个任务槽代表TaskManager的一个固定的资源子集,每个TaskManager配置多个slot。由于Flink允许Sub-Tasks共享slot,一个Slot可以运行多个Sub-Task,但是这些Sub-Task必须是来自同一个Job的不同Task的Sub-Task。注意:同一个slot不能执行同一个Task的多个subTask,另外要注意,不是说一个slot里就只有一个线程,可能会有多个不同Task的Sub-Task,也就是多个线程的。slot目前仅对内存有限制,cpu无法限制。
任务槽数的指定,由参数 taskmanager.numberOfTaskSlots 决定。注意这里还会涉及一个问题就是因为是运行在yarn上的所以就会涉及到container的cpu个数分配,就会涉及一个配置项 yarn.containers.vcores(该值生效需要yarn配置调度器为org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler),该参数默认值是-1,没配置就会去取taskmanager.numberOfTaskSlots的值,也就是 taskmanager.numberOfTaskSlots是多少就会分配多少cpu给该TaskManager。不过如果配置了 yarn.containers.vcores为具体值,则分配给该TaskManager的cpu数就是yarn.containers.vcores的具体值。当然注意分配多少cpu给TaskManager和task slot没关系,只是他只能用这么多cpu。
所以运行脚本命令时可以通过 -Dtaskmanager.numberOfTaskSlots=3 来指定
任务槽共享后形成 ============>
4. 实践案例
测试1:parallelism设置为5,task slot设置为2,则计算 5/2 向上取整就是3个TaskManager
bash bin/flink run -t yarn-per-job -d -p 5 -Dtaskmanager.numberOfTaskSlots=2 ./examples/streaming/TopSpeedWindowing.jar
测试2:parallelism设置为6,task slot设置为3,则计算 6/3 向上取整就是2个TaskManager
bash bin/flink run -t yarn-per-job -d -p 6 -Dtaskmanager.numberOfTaskSlots=3 ./examples/streaming/TopSpeedWindowing.jar