-
Notifications
You must be signed in to change notification settings - Fork 277
feat: Various improvements to memory pool configuration, logging, and documentation #2538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
b3b0a85
Refactor memory pool setup
andygrove 191bbc4
logging
andygrove 2b1242e
improve logging
andygrove f42be8f
improve logging
andygrove 6e987af
prep for review
andygrove 8ef56eb
revert
andygrove 43e83c2
more mem pool config choices
andygrove ecce61e
save
andygrove f3051ba
docs
andygrove f364962
docs
andygrove edc3d0d
logging
andygrove 5f5f95e
trace logging
andygrove 8c8ad98
logging
andygrove 83ecd6e
revert some changes
andygrove 07c69e7
revert some changes
andygrove 7e4a482
revert some changes
andygrove 648f3ee
revert some changes
andygrove 767866b
docs
andygrove d04d676
docs
andygrove 7fc62b6
upmerge
andygrove c1a2053
fix merge conflict
andygrove e36785b
address feedback
andygrove 4848f64
upmerge
andygrove 5e812de
separate memory pool config for on-heap vs off-heap
andygrove 31e9914
remove on-heap memory tuning docs
andygrove 2e125a1
docs
andygrove e35f7e8
address feedback + format
andygrove 303ba75
docs
andygrove c333959
formatting
andygrove c39afd9
remove references to fair_unified_global
andygrove 4816437
use toDouble instead of toFloat
andygrove File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,41 +36,15 @@ than before. See the [Determining How Much Memory to Allocate] section for more | |
|
|
||
| [Determining How Much Memory to Allocate]: #determining-how-much-memory-to-allocate | ||
|
|
||
| Comet supports Spark's on-heap (the default) and off-heap mode for allocating memory. However, we strongly recommend | ||
| using off-heap mode. Comet has some limitations when running in on-heap mode, such as requiring more memory overall, | ||
| and requiring shuffle memory to be separately configured. | ||
| ### Configuring Comet Memory | ||
|
|
||
| ### Configuring Comet Memory in Off-Heap Mode | ||
|
|
||
| The recommended way to allocate memory for Comet is to set `spark.memory.offHeap.enabled=true`. This allows | ||
| Comet to share an off-heap memory pool with Spark, reducing the overall memory overhead. The size of the pool is | ||
| Comet shares an off-heap memory pool with Spark. The size of the pool is | ||
| specified by `spark.memory.offHeap.size`. For more details about Spark off-heap memory mode, please refer to | ||
| [Spark documentation]. For full details on configuring Comet memory in off-heap mode, see the [Advanced Memory Tuning] | ||
| section of this guide. | ||
|
|
||
| [Spark documentation]: https://spark.apache.org/docs/latest/configuration.html | ||
|
|
||
| ### Configuring Comet Memory in On-Heap Mode | ||
|
|
||
| ```{warning} | ||
| Support for on-heap memory pools is deprecated and will be removed from a future release. | ||
| ``` | ||
|
|
||
| Comet is disabled by default in on-heap mode, but can be enabled by setting `spark.comet.exec.onHeap.enabled=true`. | ||
|
|
||
| When running in on-heap mode, Comet memory can be allocated by setting `spark.comet.memoryOverhead`. If this setting | ||
| is not provided, it will be calculated by multiplying the current Spark executor memory by | ||
| `spark.comet.memory.overhead.factor` (default value is `0.2`) which may or may not result in enough memory for | ||
| Comet to operate. It is not recommended to rely on this behavior. It is better to specify `spark.comet.memoryOverhead` | ||
| explicitly. | ||
|
|
||
| Comet supports native shuffle and columnar shuffle (these terms are explained in the [shuffle] section below). | ||
| In on-heap mode, columnar shuffle memory must be separately allocated using `spark.comet.columnar.shuffle.memorySize`. | ||
| If this setting is not provided, it will be calculated by multiplying `spark.comet.memoryOverhead` by | ||
| `spark.comet.columnar.shuffle.memory.factor` (default value is `1.0`). If a shuffle exceeds this amount of memory | ||
| then the query will fail. For full details on configuring Comet memory in on-heap mode, see the [Advanced Memory Tuning] | ||
| section of this guide. | ||
|
|
||
| [shuffle]: #shuffle | ||
|
|
||
| [Advanced Memory Tuning]: #advanced-memory-tuning | ||
|
|
@@ -93,7 +67,7 @@ Baseline Spark Performance | |
|
|
||
| Comet Performance | ||
|
|
||
| - Comet requires at least 5 GB of RAM in off-heap mode and 6 GB RAM in on-heap mode, but performance at this level | ||
| - Comet requires at least 5 GB of RAM, but performance at this level | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it onheap or offheap? |
||
| is around 340 seconds, which is significantly faster than Spark with any amount of RAM | ||
| - Comet running in off-heap with 8 cores completes the benchmark in 295 seconds, more than 2x faster than Spark | ||
| - It is worth noting that running Comet with only 4 cores and 4 GB RAM completes the benchmark in 520 seconds, | ||
|
|
@@ -114,79 +88,30 @@ Workarounds for this problem include: | |
|
|
||
| ## Advanced Memory Tuning | ||
|
|
||
| ### Configuring Off-Heap Memory Pools | ||
| ### Configuring Comet Memory Pools | ||
|
|
||
| Comet implements multiple memory pool implementations. The type of pool can be specified with `spark.comet.exec.memoryPool`. | ||
|
|
||
| The valid pool types for off-heap mode are: | ||
| The valid pool types are: | ||
|
|
||
| - `fair_unified` (default when `spark.memory.offHeap.enabled=true` is set) | ||
| - `greedy_unified` | ||
|
|
||
| Both of these pools share off-heap memory between Spark and Comet. This approach is referred to as | ||
| unified memory management. The size of the pool is specified by `spark.memory.offHeap.size`. | ||
|
|
||
| The `greedy_unified` pool type implements a greedy first-come first-serve limit. This pool works well for queries that do not | ||
| need to spill or have a single spillable operator. | ||
| Comet's memory accounting isn't 100% accurate and this can result in Comet using more memory than it reserves, | ||
| leading to out-of-memory exceptions. To work around this issue, it is possible to | ||
| set `spark.comet.exec.memoryPool.fraction` to a value less than `1.0` to restrict the amount of memory that can be | ||
| reserved by Comet. | ||
|
|
||
| The `fair_unified` pool type prevents operators from using more than an even fraction of the available memory | ||
| The `fair_unified` pool types prevents operators from using more than an even fraction of the available memory | ||
| (i.e. `pool_size / num_reservations`). This pool works best when you know beforehand | ||
| the query has multiple operators that will likely all need to spill. Sometimes it will cause spills even | ||
| when there is sufficient memory in order to leave enough memory for other operators. | ||
|
|
||
| ### Configuring On-Heap Memory Pools | ||
|
|
||
| ```{warning} | ||
| Support for on-heap memory pools is deprecated and will be removed from a future release. | ||
| ``` | ||
|
|
||
| When running in on-heap mode, Comet will use its own dedicated memory pools that are not shared with Spark. | ||
|
|
||
| The type of pool can be specified with `spark.comet.exec.memoryPool`. The default setting is `greedy_task_shared`. | ||
|
|
||
| The valid pool types for on-heap mode are: | ||
|
|
||
| - `greedy` | ||
| - `greedy_global` | ||
| - `greedy_task_shared` | ||
| - `fair_spill` | ||
| - `fair_spill_global` | ||
| - `fair_spill_task_shared` | ||
| - `unbounded` | ||
|
|
||
| Pool types ending with `_global` use a single global memory pool between all tasks on same executor. | ||
|
|
||
| Pool types ending with `_task_shared` share a single memory pool across all attempts for a single task. | ||
|
|
||
| Other pool types create a dedicated pool per native query plan using a fraction of the available pool size based on number of cores | ||
| and cores per task. | ||
|
|
||
| The `greedy*` pool types use DataFusion's [GreedyMemoryPool], which implements a greedy first-come first-serve limit. This | ||
| pool works well for queries that do not need to spill or have a single spillable operator. | ||
|
|
||
| The `fair_spill*` pool types use DataFusion's [FairSpillPool], which prevents spillable reservations from using more | ||
| than an even fraction of the available memory sans any unspillable reservations | ||
| (i.e. `(pool_size - unspillable_memory) / num_spillable_reservations`). This pool works best when you know beforehand | ||
| the query has multiple spillable operators that will likely all need to spill. Sometimes it will cause spills even | ||
| when there was sufficient memory (reserved for other operators) to avoid doing so. Unspillable memory is allocated in | ||
| a first-come, first-serve fashion | ||
|
|
||
| The `unbounded` pool type uses DataFusion's [UnboundedMemoryPool], which enforces no limit. This option is useful for | ||
| development/testing purposes, where there is no room to allow spilling and rather choose to fail the job. | ||
| Spilling significantly slows down the job and this option is one way to measure the best performance scenario without | ||
| adjusting how much memory to allocate. | ||
|
|
||
| [GreedyMemoryPool]: https://docs.rs/datafusion/latest/datafusion/execution/memory_pool/struct.GreedyMemoryPool.html | ||
| [FairSpillPool]: https://docs.rs/datafusion/latest/datafusion/execution/memory_pool/struct.FairSpillPool.html | ||
| [UnboundedMemoryPool]: https://docs.rs/datafusion/latest/datafusion/execution/memory_pool/struct.UnboundedMemoryPool.html | ||
|
|
||
| ### Configuring spark.executor.memoryOverhead in On-Heap Mode | ||
|
|
||
| In some environments, such as Kubernetes and YARN, it is important to correctly set `spark.executor.memoryOverhead` so | ||
| that it is possible to allocate off-heap memory when running in on-heap mode. | ||
|
|
||
| Comet will automatically set `spark.executor.memoryOverhead` based on the `spark.comet.memory*` settings so that | ||
| resource managers respect Apache Spark memory configuration before starting the containers. | ||
| The `greedy_unified` pool type implements a greedy first-come first-serve limit. This pool works well for queries that do not | ||
| need to spill or have a single spillable operator. | ||
|
|
||
| ## Optimizing Joins | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default is 1.0 so that this change is not a breaking change