Repository navigation
[SPARK-47208][CORE] Allow overriding base overhead memory - #45240
jpcorreia99 wants to merge 9 commits into
Conversation
There was a problem hiding this comment.
I order to minimize the changes to existing logic, I chose to make this flag not have a default and instead write the logic to check if it is not set and use the existing constant.
However, from a code cleaniness and maintenance standpoint, I think the constant can be deleted and the flag value defaulted to 384Mib.
@Reviewer, what's your view here?
There was a problem hiding this comment.
I think it would be cleaner just to have the defaults of the configs 384.
|
Hey @HyukjinKwon, would you happen to have the time to give this a review or point me to someone who might? |
|
This isn't really my area. cc @tgravescs FYI |
|
can you provide more details as to why this is needed? Its yet another configuration for memory overhead when we already have multiple. I assume you aren't trying to make the minimum lower because you say using a lot of off-heap memory. You can manually set the memoryoverhead vs setting this new config, so what use case is this trying to fix? |
|
@tgravescs very fair point! We preconfigure the spark nodes we provide to users with a global config, but then allow the users to override some of the fields. The reason why we don't explicitly set the memory overhead is because we could accidentally be reducing the overall memory the user has access to. As an example, we'd like to have at least 500Mb of overhead. User has requested a 30Gb driver. If we directly set the memory overhead to 500Mb, we'd be cutting the overhead available to the user by 2.5Gb (as overhead memory, when not directly stated, is calculated as 10% of JVM). We also don't want to be changing the overhead factor since these are global config. If we'd like to have at least a 500Mb overhead and we have a default memory of 2Gb, we'd need to set up the factor at 0.25. But then, if the user comes and asks for a 30Gb driver, he'd also receive 7.5Gb in overhead, which is excessive. As such, defining a global overhead memory minimum would work best if you want to have configurable memory settings and reasonable overhead defaults. |
tgravescs
left a comment
There was a problem hiding this comment.
ok, for an overall cluster config that makes sense, but on the other hand you are increasing the minimum for everyone as well and if they don't need the extra memory its wasting it but I guess that is a trade off. I can see the use case, left some comments
There was a problem hiding this comment.
this should be 4.0.0. This is a new feature so generally wouldn't be back ported, at least without discussion.
There was a problem hiding this comment.
driver and AM aren't necessarily the same process. In cluster mode it is but in client mode it isn't (see spark.yarn.am.memoryOverheah) - https://spark.apache.org/docs/latest/running-on-yarn.html.
Unless you have a use case for the app master doing native stuff, which I don't see, I think this should stay the same (384) or if you have a use case for it we should have a separate config for it since its a YARN specific thing.
There was a problem hiding this comment.
I may be misunderstanding something, but doesn't the fact that above we have
private val driverMinimumMemoryOverhead =
if (isClusterMode) {
sparkConf.get(DRIVER_MIN_MEMORY_OVERHEAD)
} else {
ResourceProfile.MEMORY_OVERHEAD_MIN_MIB
}
guarantee that the changes are only applied in cluster mode, which is case where it actually corresponds to the driver?
There was a problem hiding this comment.
I think it would be cleaner just to have the defaults of the configs 384.
|
I would like to understand the usecase better here - It is still unclear to me what characteristics you are shooting for by this PR. Reduction in OOM is mentioned as a usecase - but overhead does not impact that, heap memory does.
Any increase in overhead memory implies reduction in available heap memory if the max container memory has a upper limit and it is at that limit (if container memory is not limited - there is no impact of memory available to user, tune memory and overhead independently). The reason behind the question is, I am trying to understand if the default min (which was estimated quite a while ago) needs to be relooked or not - and understanding why your deployment needs a higher min will help. |
mridulm
left a comment
There was a problem hiding this comment.
We can simplify the PR by setting default of spark.driver|executor.minMemoryOverhead to 384, and replace existing use of 384 with this config.
There was a problem hiding this comment.
set the default here to 384 - and use this instead of existing 384
|
Hey @tgravescs I've now addressed your comments and also answered @mridulm, whenever you have the time, I'd highly appreciate if you could give it another review. |
| </tr> | ||
| <tr> | ||
| <td><code>spark.driver.minMemoryOverhead</code></td> | ||
| <td>384Mib</td> |
There was a problem hiding this comment.
@tgravescs just want to make sure I'm being correct here.
I create this flag with .createWithDefaultString("384m"). Is it correct for me to write here Mib instead of m for clarity to the reader or should I stick to exactly the value it contains?
There was a problem hiding this comment.
I think I would put it at "384m" to be more consistent with other docs and be format user would specify if changing.
mridulm
left a comment
There was a problem hiding this comment.
Looks good to me, just one point for discussion
| overheadFactor: Double): Long = { | ||
| overHeadMemFromConf.getOrElse(math.max((overheadFactor * executorMemoryMiB).toInt, | ||
| ResourceProfile.MEMORY_OVERHEAD_MIN_MIB)) | ||
| minimumOverHeadMemoryFromConf)) |
There was a problem hiding this comment.
Discuss:
Do we need MEMORY_OVERHEAD_MIN_MIB after this PR is merged ?
If no, remove that field ?
yarn client mode AM overhead can be specified in that file, does not need to be in ResourceProfile ... ditto for suites.
Thoughts @tgravescs, @jpcorreia99 ?
There was a problem hiding this comment.
I do agree, at this point, outside of tests, ResourceProfile.MEMORY_OVERHEAD_MIN_MIB has only one usage in client AM overhead, so will make that change, can revert if @tgravescs disagrees
There was a problem hiding this comment.
I agree with removing it.
| </tr> | ||
| <tr> | ||
| <td><code>spark.driver.minMemoryOverhead</code></td> | ||
| <td>384Mib</td> |
There was a problem hiding this comment.
I think I would put it at "384m" to be more consistent with other docs and be format user would specify if changing.
|
@tgravescs thank you for the comments, I've addressed them in cd03ec8 |
|
Looks good, thanks @jpcorreia99 |
|
@tgravescs great! Any timeline on merging this? |
|
Merged to master, thanks @mridulm @jpcorreia99 |
What changes were proposed in this pull request?
We can already select the desired overhead memory directly via the
spark.driver/executor.memoryOverheadflags, however, if that flag is not present the overhead memory calculation goes as follows:This PR adds two new spark configs:
spark.driver.minMemoryOverheadandspark.executor.minMemoryOverhead, which can be used to override the 384Mib minimum value.The memory overhead calculation will now be :
Why are the changes needed?
There are certain times where being able to override the 384Mb minimum directly can be beneficial. We may have a scenario where a lot of off-heap operations are performed (ex: using package managers/native compression/decompression) where we don't have a need for a large JVM heap but we may still need a signficant amount of memory in the spark node.
Using the
memoryOverheadFactorconfig flag may not prove appropriate, since we may not want the overhead allocation to directly scale with JVM memory, as a cost saving/resource limitation problem.Does this PR introduce any user-facing change?
Yes, as described above, two new flags have been added to the spark config. No break of existing behaviours.
How was this patch tested?
Added tests for 3 cases:
spark.driver/executor.memoryOverheadis set, then the new changes have no effect.spark.driver/executor.minMemoryOverheadis set and its value is higher than 'spark.driver/executor.memory' * 'spark.driver/executor.memoryOverheadFactor', the total memory will be the allocated JVM memory +spark.driver/executor.minMemoryOverheadspark.driver/executor.minMemoryOverheadbut its value is lower than 'spark.driver/executor.memory' * 'spark.driver/executor.memoryOverheadFactor', the total memory will be the allocated JVM memory + 'spark.driver/executor.memory' * 'spark.driver/executor.memoryOverheadFactor'.Was this patch authored or co-authored using generative AI tooling?
No