Flink的Parallelism并行度

一.Flink的Parallelism并行度

Flink的Parallelism并行度

  1. 在flink-conf.yaml中通过parallelism.default配置项给所有execution nvironments指定系统级的默认parallelism;
  2. 在ExecutionEnvironment里头可以通过setParallelism来给operators、data sources、data sinks设置默认的parallelism;
  3. 如果operators、data sources、data sinks自己有设置parallelism则会覆盖ExecutionEnvironment设置的parallelism

设置并行度

Flink 应用程序在一个像集群这样的分布式环境中并行执行。当一个数据流程序提交到作业管理器执行时,系统将会创建一个数据流图,然后准备执行需要的操作符。每一个操作符将会并行化到一个或者多个任务中去。每个算子的并行任务都会处理这个算子的输入流中的一份子集。一个算子并行任务的个数叫做算子的并行度。它决定了算子执行的并行化程度,以及这个算子能处理多少数据量。算子的并行度可以在执行环境这个层级来控制,也可以针对每个不同的算子设置不同的并行度。默认情况下,应用程序中所有算子的并行度都将设置为执行环境的并行度。执行环境的并行度(也就是所有算子的默认并行度)将在程序开始运行时自动初始化。如果应用程序在本地执行环境中运行,并行度将被设置为CPU 的核数。当我们把应用程序提交到一个处于运行中的Flink集群时,执行环境的并行度将被设置为集群默认的并行度,除非我们在客户端提交应用程序时显式的设置好并行度。通常情况下,将算子的并行度定义为和执行环境并行度相关的数值会是个好主意。
这允许我们通过在客户端调整应用程序的并行度就可以将程序水平扩展了。我们可以使用以下代码来访问执行环境的默认并行度。
我们还可以重写执行环境的默认并行度,但这样的话我们将再也不能通过客户端来控制应用程序的并行度了。
算子默认的并行度也可以通过重写来明确指定。在下面的例子里面,数据源的操作符将会按照环境默认的并行度来并行执行,map 操作符的并行度将会是默认并行度的2倍,sink 操作符的并行度为2。

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
int defaultP = env.getParallelism();
env
.addSource(new CustomSource())
.map(new MyMapper())
.setParallelism(defaultP * 2)
.print()
.setParallelism(2);

当我们通过客户端将应用程序的并行度设置为16 并提交执行时,source 操作符的并行度为16,mapper 并行度为32,sink 并行度为2。如果我们在本地环境运行应用程序的话,例如在IDE 中运行,机器是8 核,那么source 任务将会并行执行在8 个任务上面,mapper 运行在16 个任务上面,sink 运行在2 个任务上面。
示例:

package test

/**
 * @author LamHenry

 * @date 2022/9/20 17:35
 */

import org.apache.flink.api.scala.ExecutionEnvironment

import scala.collection.mutable.ArrayBuffer

object PartitionDataSet {
  def main(args: Array[String]): Unit = {
    val env = ExecutionEnvironment.getExecutionEnvironment
    import org.apache.flink.api.scala._

    val array = ArrayBuffer (
      (1, "hello"),
      (2, "hello"),
      (4, "hello"),
      (3, "hello")
    )
    env.setParallelism ( 3 )

    val sourceDataSet: DataSet[(Int, String)] = env.fromCollection ( array )
    //partitionByHash:按照指定的字段hashPartitioner分区
    sourceDataSet.partitionByHash ( 0 ).mapPartition ( x => {
      x.foreach ( y => {
        println ( "当前线程ID:" + Thread.currentThread ( ).getId + "===" + y._1 )
      } )
      x
    }
    ).print ( )
    println ( "--------------------------------------" )
    //partitionByRange:按照指定的字段进行范围分区
    sourceDataSet.partitionByRange ( x => x._1 ).mapPartition ( x => {
      x.foreach ( y => {
        println ( "当前线程ID:" + Thread.currentThread ( ).getId + "===" + y._1 )
      } )
      x
    } ).print()
  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值