[VL] Reuse driver-built broadcast hash tables across queries - #12872
Draft
zhouyuan wants to merge 1 commit into
Draft
[VL] Reuse driver-built broadcast hash tables across queries#12872zhouyuan wants to merge 1 commit into
zhouyuan wants to merge 1 commit into
Conversation
Driver-side broadcast hash table build already caches the serialized hash table, but it keys the cache by the BroadcastExchangeExec instance, so the entry can only be reused by exchange reuse inside one query. Workloads that run the same queries over and over, e.g. the concurrent streams of a TPC-DS throughput run, collect, build, serialize and broadcast the very same hash table again for every query. Add a driver-side cache that keys the built relation by the canonicalized build side plan plus everything the content of the hash table depends on: the normalized build keys, the build schema, the substrait join type, the build side, the filter build column ordinals, the null aware / existence join flags, the bloom filter pushdown size and whether duplicates were dropped. Expression ids are normalized against the build side output, so two instances of the same query map to the same key. The lookup happens before the build side is collected, so a hit skips the collect job, the hash table build and the serialization, and replays the row count and data size of the job that built the relation into the exchange metrics. When the very same relation object is broadcast again, the broadcast created the first time is handed out as well, which also skips re-serializing and re-uploading the blocks. Build sides with non-deterministic expressions or subqueries, including the runtime filters of dynamic partition pruning, are never shared. Reuse assumes the data behind a build side does not change while the application is running, and cached relations hold driver memory until they are evicted, so the cache is off by default and bounded by size: spark.gluten.sql.columnar.backend.velox.driverSideBroadcastHashTableCache.enabled spark.gluten.sql.columnar.backend.velox.driverSideBroadcastHashTableCache.maxSize
|
Run Gluten Clickhouse CI on x86 |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What changes are proposed in this pull request?
Driver-side broadcast hash table build already caches the serialized hash table, but it keys the cache by the BroadcastExchangeExec instance, so the entry can only be reused by exchange reuse inside one query. Workloads that run the same queries over and over, e.g. the concurrent streams of a TPC-DS throughput run, collect, build, serialize and broadcast the very same hash table again for every query.
Add a driver-side cache that keys the built relation by the canonicalized build side plan plus everything the content of the hash table depends on: the normalized build keys, the build schema, the substrait join type, the build side, the filter build column ordinals, the null aware / existence join flags, the bloom filter pushdown size and whether duplicates were dropped. Expression ids are normalized against the build side output, so two instances of the same query map to the same key.
The lookup happens before the build side is collected, so a hit skips the collect job, the hash table build and the serialization, and replays the row count and data size of the job that built the relation into the exchange metrics. When the very same relation object is broadcast again, the broadcast created the first time is handed out as well, which also skips re-serializing and re-uploading the blocks.
Build sides with non-deterministic expressions or subqueries, including the runtime filters of dynamic partition pruning, are never shared. Reuse assumes the data behind a build side does not change while the application is running, and cached relations hold driver memory until they are evicted, so the cache is off by default and bounded by size:
spark.gluten.sql.columnar.backend.velox.driverSideBroadcastHashTableCache.enabled
spark.gluten.sql.columnar.backend.velox.driverSideBroadcastHashTableCache.maxSize
How was this patch tested?
new tests
Was this patch authored or co-authored using generative AI tooling?
Claude Opus
IBM Bob