Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Not A Bug
-
2.3.1
-
None
-
None
Description
When deploying on YARN, only executorMemory is used to launch executors in YarnAllocator.scala#L529:
try { new ExecutorRunnable( Some(container), conf, sparkConf, driverUrl, executorId, executorHostname, executorMemory, executorCores, appAttemptId.getApplicationId.toString, securityMgr, localResources ).run() updateInternalState() } catch {
However, resource capability requested for each executor is executorMemory + memoryOverhead in YarnAllocator.scala#L142:
// Resource capability requested for each executors private[yarn] val resource = Resource.newInstance(executorMemory + memoryOverhead, executorCores)
This means that the amount of memoryOverhead will not be used in running the job, hence wasted.
Checking both k8s and Mesos, it looks like they both include overhead memory.
For k8s, in ExecutorPodFactory.scala#L179:
val executorContainer = new ContainerBuilder() .withName("executor") .withImage(executorContainerImage) .withImagePullPolicy(imagePullPolicy) .withNewResources() .addToRequests("memory", executorMemoryQuantity) .addToLimits("memory", executorMemoryLimitQuantity) .addToRequests("cpu", executorCpuQuantity) .endResources() .addAllToEnv(executorEnv.asJava) .withPorts(requiredPorts.asJava) .addToArgs("executor") .build()
For Mesos, inMesosSchedulerUtils.scala#L374:
/** * Return the amount of memory to allocate to each executor, taking into account * container overheads. * * @param sc SparkContext to use to get `spark.mesos.executor.memoryOverhead` value * @return memory requirement as (0.1 * memoryOverhead) or MEMORY_OVERHEAD_MINIMUM * (whichever is larger) */ def executorMemory(sc: SparkContext): Int = { sc.conf.getInt("spark.mesos.executor.memoryOverhead", math.max(MEMORY_OVERHEAD_FRACTION * sc.executorMemory, MEMORY_OVERHEAD_MINIMUM).toInt) + sc.executorMemory }