Spark on Yarn的内存分配

1 初始化配置

// Client.scala
// 初始化yarn client
private val yarnClient = YarnClient.createYarnClient
// 初始化hadoop配置
private val hadoopConf = new YarnConfiguration(SparkHadoopUtil.newConfiguration(sparkConf))
// 获取集群模式,这里使用默认的client模式,所以isClusterMode的值为0
private val isClusterMode = sparkConf.get("spark.submit.deployMode", "client") == "cluster"

2 ApplicationMaster(AM)的相关配置

2.1 amMemory

AM的内存,根据集群模式的不同,分配的内存也不相同

// Client.scala
// 配置AM的内存
private val amMemory = if (isClusterMode) {
    // cluster模式下使用driver的内存配置
    sparkConf.get(DRIVER_MEMORY).toInt
} else {
    // client模式下使用的是AM自己的配置
    sparkConf.get(AM_MEMORY).toInt
}

cluster 模式下,AM的内存等于driver的内存,通过改变配置文件中的 spark.driver.memory 进行配置,默认值为 1g

// TODO:为什么可以等于driver的内存大小?

// package.scala
private[spark] val DRIVER_MEMORY = ConfigBuilder("spark.driver.memory")
    .doc("Amount of memory to use for the driver process, in MiB unless otherwise specified.")
    .bytesConf(ByteUnit.MiB)
    .createWithDefaultString("1g")

client 模式下,AM的内存通过改变配置文件中的 spark.yarn.am.memory 进行配置,默认值为 512M

// config.scala
private[spark] val AM_MEMORY = ConfigBuilder("spark.yarn.am.memory")
    .bytesConf(ByteUnit.MiB)
    .createWithDefaultString("512m")

2.2 amMemoryOverhead

堆外内存(off-heap memory) ,它负责诸如虚拟机开销、内部字符串开销以及其他本地开销等。这往往随容器大小(通常为6-10%)而增长。

// client.scala
private val amMemoryOverhead = {
    val amMemoryOverheadEntry = if (isClusterMode) DRIVER_MEMORY_OVERHEAD else AM_MEMORY_OVERHEAD
    sparkConf.get(amMemoryOverheadEntry).getOrElse(
      // (MEMORY_OVERHEAD_FACTOR * amMemory)
      // 和MEMORY_OVERHEAD_MIN相比取最大值
      math.max((MEMORY_OVERHEAD_FACTOR * amMemory).toLong, MEMORY_OVERHEAD_MIN)).toInt
}

// YarnSparkHadoopUtil.scala
val MEMORY_OVERHEAD_FACTOR = 0.10
val MEMORY_OVERHEAD_MIN = 384L

// 因此上方的计算结果为max((0.1*1g).toLong, 384L) = 384

cluster 模式下,amMemoryOverhead 的内存等于driver的memoryOverhead内存,通过改变配置文件中的 spark.driver.memoryOverhead 进行配置

// package.scala
private[spark] val DRIVER_MEMORY_OVERHEAD = ConfigBuilder("spark.driver.memoryOverhead")
    .doc("The amount of off-heap memory to be allocated per driver in cluster mode, " +
      "in MiB unless otherwise specified.")
    .bytesConf(ByteUnit.MiB)
    .createOptional

根据官网的配置信息,该值为 max(driverMemory * 0.10,384M)
两个结果都相互印证了amMemoryOverhead的计算方式,然而随着driver内存的增加,如果超过了3.84g,那amMemoryOverhead的值将会随着driver内存的增加而增加。

client 模式下,amMemoryOverhead 的内存通过改变配置文件中的 spark.yarn.am.memoryOverhead 进行配置

// config.scala
private[spark] val AM_MEMORY_OVERHEAD = ConfigBuilder("spark.yarn.am.memoryOverhead")
    .bytesConf(ByteUnit.MiB)
    .createOptional

该部分的计算方式与 cluster 模式的计算方式一致,唯一不同的是amMemoryOverhead的值不受driver内存大小的影响,而是受自身配置的影响,当amMemory内存超过3.84g时,amMemoryOverhead随amMemory增加而增加。

2.3 amCores

// Client.scala
// 分配给ApplicationMaster的core数量
private val amCores = if (isClusterMode) {
    sparkConf.get(DRIVER_CORES)
} else {
    sparkConf.get(AM_CORES)
}

// config.scala
// client模式下的amCores,默认为1
private[spark] val AM_CORES = ConfigBuilder("spark.yarn.am.cores")
    .intConf
    .createWithDefault(1)
    
// config.scala
// cluster模式下的amCores,默认为1
private[spark] val DRIVER_CORES = ConfigBuilder("spark.driver.cores")
    .intConf
    .createWithDefault(1)

3 executor相关配置

3.1 executorMemory

// Client.scala
// 计算executorMemory
private val executorMemory = sparkConf.get(EXECUTOR_MEMORY)

// package.scala
// 默认大小为1g
private[spark] val EXECUTOR_MEMORY = ConfigBuilder("spark.executor.memory")
    .doc("Amount of memory to use per executor process, in MiB unless otherwise specified.")
    .bytesConf(ByteUnit.MiB)
    .createWithDefaultString("1g")

3.2 executorMemoryOverhead

// Client.scala
// 计算executorMemoryOverhead
private val executorMemoryOverhead = sparkConf.get(EXECUTOR_MEMORY_OVERHEAD).getOrElse(
    math.max((MEMORY_OVERHEAD_FACTOR * executorMemory).toLong, MEMORY_OVERHEAD_MIN)).toInt

与之前计算amMemoryOverhead的方式一样,在executorMemory等于1g的情况下,计算结果为384M

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值