Uh oh!
There was an error while loading. Please reload this page.
AWS: Use executor service by default when performing batch deletion of files - #5379
Conversation
amogh-jahagirdar
commented
Jul 29, 2022
I'm running AWS integ tests to validate this. |
0e0eaed to
8ec83ddCompared44f31e to
7183866CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
7183866 to
389747bCompare389747b to
0f566feCompare| if (!awsProperties.isS3DeleteEnabled()) { | ||
| return; | ||
| if (awsProperties.isS3DeleteEnabled()) { | ||
| SetMultimap<String, String> bucketToObjects = computeBucketToObjects(paths); |
There was a problem hiding this comment.
We are now eagerly computing the bucket to objects mapping up front, as opposed to before where we would iterate over the paths, keep track of the objects per bucket and if for a given bucket the size of the objects is the batch size, the deletion would get triggered (and the mapping would get removed).
Now, it's all up front, so there would be more memory consumption but I think it should be ok. 1 million objects with a max key size of 1024 bytes is 1 GB representation of paths maintained in memory.
There was a problem hiding this comment.
1gb does sounds like a lot , example on the spark driver. Is it still possible to do it via streaming, ie submit the deletion batch to Tasks once it gets full?
There was a problem hiding this comment.
can we try to use https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/paginators/ListObjectsV2Iterable.html so that the list is dynamically loaded instead of buffered upfront
There was a problem hiding this comment.
@jackye1995 I don't think we need a separate API for listing actually, we are already given the iterable of paths. This iterable can be the ListObjectsV2Iterable (which is done as of today in the deletePrefix).
For lazily loading in memory, and still deleting in a concurrent manner we can do the following:
1.) Still use the previous approach and constructing the bucket/key from the path and keeping track of when the objects for a bucket hits a certain batch size.
2.) Instead of using task framework, submit the deletion to an executor service and just keep track of the future. we don't want to use Tasks because it will wait for the completion internally.
We want to just submit the batch deletion and move on, and then at the very end check the statuses of all those tasks. So using the underlying executor service fits that pattern. Let me know what you think.
Will update the PR.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
0f566fe to
a4e36c0CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
5be1059 to
639acf1Compare
Updated the description so it reflects the new approach. I also removed the integ test fixes, and moved them here #5413 . Thanks! |
c7059a1 to
e399c4eCompare316d6d9 to
2856de4CompareUh oh!
There was an error while loading. Please reload this page.
0922b40 to
eeeda0cCompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
95ad675 to
63374cbCompareaokolnychyi
commented
Aug 10, 2022
Let me take another look tomorrow. Sorry for the delay! |
| .map(error -> String.format("s3://%s/%s", request.bucket(), error.key())) | ||
| .collect(Collectors.toList())); | ||
| } | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
[doubt] Any reason we are catching a generic exception here ?
There was a problem hiding this comment.
Yeah I think in case of any failure we should surface a BulkDeletionFailure at the end. So catching the generic exception allows us to handle any failure, treat it as a failure to delete the entire batch, and add that to the failed files list. I'm not sure of any other case where we want to surface something else. We're logging the specific exception so that folks can debug.
Uh oh!
There was an error while loading. Please reload this page.
aokolnychyi
left a comment
There was a problem hiding this comment.
This change looks good to me.
After a closer look, passing an explicit executor started to make more sense to me. I think we may add that overloaded method back once we consume these changes in other places.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
63374cb to
a29ba42Compareamogh-jahagirdar
commented
Aug 10, 2022
Right, this is my thought as well. Once we see there is a need for the API we can add that, it's harder to go the other way. Thanks for the review @aokolnychyi ! |
jackye1995
commented
Aug 10, 2022
I think we get enough approvals, thanks for the work @amogh-jahagirdar , and thanks everyone for the review! |
Thanks everyone for the reviews! @jackye1995@singhpk234@aokolnychyi@szehon-ho |
(cherry picked from commit f6d9ddc)
Update the S3FileIO to lazily load batches and use the existing deletion threadpool for performing concurrent S3#RemoveObjects calls.
This will be used in subsequent PRs for performing bulk deletes in procedures like removing orphan files, snapshot expiration and purging the data, manifests, old metadata files during table drop.