Spark 静态资源配置方法

1、背景

执行Spark任务,资源分配是很重要的一方面。如果配置不准确,Spark任务将耗费整个集群的机缘导致其他应用程序得不到资源。

怎么去配置Spark任务的executors,cores,memory,有如下几个因素需要考虑:

  • 数据量
  • 任务完成时间点
  • 静态或者动态的资源分配
  • 上下游应用

2、Spark应用当中术语的基本定义:

  • Partitions : 分区是大型分布式数据集的一小部分。 Spark使用分区来管理数据,这些分区有助于并行化数据处理,并且使executor之间的数据交换最小化
  • Task:任务是一个工作单元,可以在分布式数据集的分区上运行,并在单个Excutor上执行。并行执行的单位是任务级别。单个Stage中的Tasks可以并行执行
  • Executor:在一个worker节点上为应用程序创建的JVM,Executor将巡行task的数据保存在内存或者磁盘中。每个应用都有自己的一些executors,单个节点可以运行多个Executor,并且一个应用可以跨多节点。Executor始终伴随Spark应用执行过程,并且以多线程方式运行任务。spark应用的executor个数可以通过SparkConf或者命令行 –num-executor进行配置
  • Cores:CPU最基本的计算单元,一个CPU可以有一个或者多个core执行task任务,更多的core带来更高的计算效率,Spark中,cores决定了一个executor中并行task的个数
    Cluster Manager:cluster manager负责从集群中请求资源

3、cluster模式执行的Spark任务包含了如下步骤:

  1. driver端,SparkContext连接cluster manager(Standalone/Mesos/Yarn)
  2. Cluster Manager在其他应用之间定位资源,只要executor执行并且能够相互通信,可以使用任何Cluster Manager
  3. Spark获取集群中节点的Executor,每个应用都能够有自己的executor处理进程
  4. 发送应用程序代码到executor中
  5. SparkContext将Tasks发送到executors

以上步骤可以清晰看到executors个数和内存设置在spark中的重要作用。

4、静态分配

案例:6 个节点,每个节点 16 核 + 64 GB RAM

由于每个 executor 都是一个 JVM 实例,所以我们可以给每个节点分配多个 executor。

  1. 为系统的运行保留资源
    文章原文的内容是:为了保证操作系统和 hadoop 进程的运行,每个节点要预留 1 个核心 + 1 GB 内存。所以每个节点可用的资源为:15 个核心 + 63 GB RAM
    但是如果你不希望你的系统陷入高负载的情况,你可以多预留一些资源,我个人的使用经验是每个节点预留 4 个核心 + 4 GB 内存

  2. 确定每个 executor 的核心数量——“magic number”

参数说明:该参数用于设置每个Executor进程的CPU core数量。这个参数决定了每个Executor进程并行执行task线程的能力。因为每个CPU core同一时间只能执行一个task线程
研究表明,不是给 executor 分配越多的核心越好,任何一个 application 分配的核心数目超过 5 个只会导致性能下降,所以我们一般把 executor 核心数量设置为 5 及 5 以下的数字。在接下来的案例讲解中我们把核心数目设置为 5。

  1. 设置 executor 数量
    每个节点的 executor 数量 = 15 / 5 = 3, 所以总的 executor 数量为 3 * 6 = 18,由于 YARN 的 ApplicationMaster 需要占用一个 executor,所以我们设置的 executor 数量为 18 - 1 = 17。

  2. 设置 executor 分配的内存大小
    在之前的步骤中,我们给每个节点分配了 3 个 executor,每个节点可用的 RAM 是 63 GB,所以每个 executor 的内存为 63 / 3 = 21 GB。

  3. 但是 spark 在向 YARN 申请内存时,YARN 会给每个 executor 多分配大小为 overhead 的内存,而 overhead = max(384 MB, 0.1 * spark.executor.memory)。在我们的案例中 overhead = 0.1 * 21 = 2.1 GB > 384 MB,所以我们申请的内存大小为 21 - 2.1 ~ 19 GB。

  • 源码:
// from YarnAllocator
 // Executor memory in MB.
  protected val executorMemory = sparkConf.get(EXECUTOR_MEMORY).toInt
  // Additional memory overhead.其中MEMORY_OVERHEAD_MIN为384MB,MEMORY_OVERHEAD_FACTOR 为0.1
  protected val memoryOverhead: Int = sparkConf.get(EXECUTOR_MEMORY_OVERHEAD).getOrElse(
    math.max((MEMORY_OVERHEAD_FACTOR * executorMemory).toInt, MEMORY_OVERHEAD_MIN)).toInt
  // Number of cores per executor.
  protected val executorCores = sparkConf.get(EXECUTOR_CORES)
  // Resource capability requested for each executors
  private[yarn] val resource = Resource.newInstance(executorMemory + memoryOverhead, executorCores)
  1. 最终我们得到的分配方案是:每个 executor 分配 5 个核心,设置 17 个 executor, 每个 executor 分配的内存为 19 GB。写成 spark-submit 命令为:
spark-submit --master yarn\
 --executor-cores 5 
 --num-executors 17\
 --executor-memory 19 

原文

https://stackoverflow.com/questions/37871194/how-to-tune-spark-executor-number-cores-and-executor-memory

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值