Spark 4.1: Add rewrite option to enable executor cache for delete files - #17868
Spark 4.1: Add rewrite option to enable executor cache for delete files#17868anuragmantri wants to merge 2 commits into
Conversation
|
@RussellSpitzer @kinolaev - Could you take a look? Thanks! |
| | `output-spec-id` | current partition spec id | Identifier of the output partition spec. Data will be reorganized during the rewrite to align with the output partitioning. | | ||
| | `remove-dangling-deletes` | false | Remove dangling position and equality deletes after rewriting. A delete file is considered dangling if it does not apply to any live data files. Enabling this will generate an additional commit for the removal. | | ||
| | `max-files-to-rewrite` | null | This option sets an upper limit on the number of eligible files that will be rewritten. If this option is not specified, all eligible files will be rewritten. | | ||
| | `executor-cache.delete-files.enabled` | false | Use the executor cache for delete files while rewriting. Enable this when the same delete file applies to many data files, which is common with equality deletes | |
There was a problem hiding this comment.
let's try to keep this to one snake case thing.
cache-delete-files?
There was a problem hiding this comment.
Given that the Spark property is called spark.sql.iceberg.executor-cache.enabled and we already have the partial-progress.enabled option on this procedure, my preference would be executor-cache.enabled.
There was a problem hiding this comment.
I'd rather we not use a "." property if we can help. The partial progress ones are not a good example based on all the other procedure options we have. All the others use the kabob thing and I think it's because only partial progress was originally defined in the "action".
enable-executor-cache is also fine, but I don't think it really explains what the option is doing. It only effects deletes and specifically delete files so I'd try to keep the name tied to that functionality
There was a problem hiding this comment.
I kept it to cache-delete-files. This is concise and conveys the intention.
| * | ||
| * <p>Defaults to false. | ||
| */ | ||
| public static final String EXECUTOR_CACHE_DELETE_FILES_ENABLED = |
There was a problem hiding this comment.
As I mentioned above, lets just drop the other parts here, I think just CACHE_DELETE_FILES is fine
| public void testExecutorCacheForDeleteFilesDisabled() { | ||
| Table table = createTablePartitioned(1, 1); | ||
| RewriteDataFilesSparkAction action = SparkActions.get(spark).rewriteDataFiles(table); | ||
| action.execute(); |
There was a problem hiding this comment.
Ok I can see this is because we moved it into "validate"
Since we are in the same package can we just call validate rather than actually executing?
There was a problem hiding this comment.
Ok we can't do that. Maybe we should move this back to the constructor?
There was a problem hiding this comment.
We can't, because.option() is called after the constructor
There was a problem hiding this comment.
That's too bad. i'm trying to figure out how we can avoid running 3 additional spark rewrites in the tests here when all we really care about is the conf being on or off.
There was a problem hiding this comment.
Okay, I looked at all the other options tests. All test behavior. This one is different. IMO, we have covered the behavior tests in TestSparkExecutorCache so we probably don't need these tests here. I removed them. Let me know if you feel otherwise.
There was a problem hiding this comment.
Can we make the init method package-private? I checked, and the removed tests pass when calling init(0L) instead of execute.
I am also fine with the current tests in TestSparkExecutorCache.
|
LGTM. Although I prefer a slightly shorter name (see above), the current option is also fine with me. Thanks @anuragmantri for the PR! |
anuragmantri
left a comment
There was a problem hiding this comment.
Thanks for the quick reviews.
I also thought about the three options we have. It can be confusing but I kept all three. My rationale is that these serve slightly different purposes.
executor-cache.enabled- Main switch to control caching, also gates locality. Predates my PRs to add ability to disable delete files only.executor-cache.delete-files.enabled- A scan option narrowed down for delete files cache onl.cache-delete-filesthis is a rewrite option that controls 2 for scans during rewrites.
| | `output-spec-id` | current partition spec id | Identifier of the output partition spec. Data will be reorganized during the rewrite to align with the output partitioning. | | ||
| | `remove-dangling-deletes` | false | Remove dangling position and equality deletes after rewriting. A delete file is considered dangling if it does not apply to any live data files. Enabling this will generate an additional commit for the removal. | | ||
| | `max-files-to-rewrite` | null | This option sets an upper limit on the number of eligible files that will be rewritten. If this option is not specified, all eligible files will be rewritten. | | ||
| | `executor-cache.delete-files.enabled` | false | Use the executor cache for delete files while rewriting. Enable this when the same delete file applies to many data files, which is common with equality deletes | |
There was a problem hiding this comment.
I kept it to cache-delete-files. This is concise and conveys the intention.
| * | ||
| * <p>Defaults to false. | ||
| */ | ||
| public static final String EXECUTOR_CACHE_DELETE_FILES_ENABLED = |
| public void testExecutorCacheForDeleteFilesDisabled() { | ||
| Table table = createTablePartitioned(1, 1); | ||
| RewriteDataFilesSparkAction action = SparkActions.get(spark).rewriteDataFiles(table); | ||
| action.execute(); |
There was a problem hiding this comment.
Okay, I looked at all the other options tests. All test behavior. This one is different. IMO, we have covered the behavior tests in TestSparkExecutorCache so we probably don't need these tests here. I removed them. Let me know if you feel otherwise.
Related to #11648.
RewriteDataFilesSparkActionhas disabled the executor cache for delete files unconditionally since #13820. As noted in the discussion on #11648, that is the right default for position deletes but costly for equality deletes, which cannot be narrowed to a single data file while reading and are therefore re-read in full for every data file whose bounds overlap.This adds a rewrite option so users can opt back in, where a Spark executor cache setting is exposed as a rewrite option rather than a session property.
Existing Default behavior is unchanged.
Usage from SQL:
Usage from the action API:
Tests added to
TestSparkExecutorCacheassert the number of times each delete file is opened during a rewrite: 2 per delete file with the option at its default, once per data file, and 1 with the option enabled.AI Disclosure
RewriteDataFilesvia a new rewrite option, keeping the existing default, then review the change against AGENTS.md and add tests.