Skip to content

[HUDI-5279] move logic for deleting active instant to HoodieActiveTimeline#7196

Merged
YannByron merged 6 commits intoapache:masterfrom
YannByron:hudi_improve_atl
Nov 30, 2022
Merged

[HUDI-5279] move logic for deleting active instant to HoodieActiveTimeline#7196
YannByron merged 6 commits intoapache:masterfrom
YannByron:hudi_improve_atl

Conversation

@YannByron
Copy link
Contributor

Change Logs

Currently, only the logic for deleting active instant is out of HoodieActiveTimeline.
I think it's better that all the operations to active instant are concentrated to HoodieActiveTimeline.

Impact

none

Risk level (write none, low medium or high below)

none

Documentation Update

Describe any necessary documentation update if there is any new feature, config, or user-facing change

  • The config description must be updated if new configs are added or the default value of the configs are changed
  • Any new feature or user-facing change requires updating the Hudi website. Please create a Jira ticket, attach the
    ticket number here and follow the instruction to make
    changes to the website.

Contributor's checklist

  • Read through contributor's guide
  • Change Logs and Impact were stated clearly
  • Adequate tests were added if applicable
  • CI passed

@YannByron
Copy link
Contributor Author

@hudi-bot run azure

Path inFlightCommitFilePath = getInstantFileNamePath(instant.getFileName());
try {
if (metaClient.getFs().exists(inFlightCommitFilePath)) {
boolean result = metaClient.getFs().delete(inFlightCommitFilePath, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems the core change is renaming a method here: deleteInstantFileIfExists -> deleteInstantIfExists ? If that is true, i would suggest to keep as it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no.
the major change is that, when need to delete active instant in archive operation, use HoodieActiveTimeline's deleteInstantIfExists instead of calling the naked api (fs.delete). After the changes, HoodieActiveTimeline becomes the standard route to operate active instants.

For this above, merge the origin method deleteInstantFile (used in current class and subclass) and deleteInstantFileIfExists (used outside) to one, and rename to deleteInstantIfExists.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling the naked api (fs.delete).

deleteInstantFile(HoodieInstant instant) also takes a HoodieInstant param, so what's the difference here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the old way to delete active instants when archive uses deleteArchivedInstantFiles -> deleteFilesParallelize in HoodieTimelineArchiver. and deleteFilesParallelize calls fs.delete() directly.

public static <T, R> Map<T, R> parallelizeProcess(
HoodieEngineContext hoodieEngineContext,
int parallelism,
SerializableFunction<T, R> pairFunction,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems a general method for parallel processing, should not put it in FSUtils, maybe we can add a similar tool method as HoodieTimelineArchiver#deleteFilesParallelize for hoodie instants, for example HoodieTimelineArchiver#deleteInstantsParallelize

if (result) {
LOG.info("Removed instant " + instant);
} else {
throw new HoodieIOException("Could not delete instant " + instant);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method save one invocation for fs.exists, let's keep it.

@YannByron YannByron force-pushed the hudi_improve_atl branch 2 times, most recently from 1145ecb to 47f4bd8 Compare November 16, 2022 03:12
@apache apache deleted a comment from YannByron Nov 24, 2022
@XuQianJin-Stars
Copy link
Contributor

@hudi-bot run azure

@YannByron
Copy link
Contributor Author

@hudi-bot run azure

this CI has passed. @XuQianJin-Stars

Copy link
Member

@xushiyan xushiyan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few notes:

  • at timeline API level, we should not allow ignoring error; this affects data integrity
  • there is another API org.apache.hudi.common.table.timeline.HoodieActiveTimeline#deleteInstantFile(org.apache.hudi.common.table.timeline.HoodieInstant) to be consolidated/dedup'ed
  • pls file jira as this touches critical code path, also properly fill the PR template "Impact" and "Risk" sections
  • pls help increase UT coverage for critical APIs wherever applicable

success &= result.getValue();
Map<HoodieInstant, Boolean> result = context.mapToPair(
instants,
instant -> ImmutablePair.of(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hide implementation: use Pair.of()

Comment on lines 587 to 590
boolean success = true;
for (Map.Entry<HoodieInstant, Boolean> entry : result.entrySet()) {
LOG.info("Archived and deleted instant " + entry.getKey().toString() + " : " + entry.getValue());
success &= entry.getValue();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can chain this with result using stream API allMatch()

Copy link
Contributor Author

@YannByron YannByron Nov 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if throw error directly if fail to delete, no return value is required.

deleteInstantFileIfExists(instant, true);
}

public boolean deleteInstantFileIfExists(HoodieInstant instant, boolean exceptionIfFailToDelete) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public boolean deleteInstantFileIfExists(HoodieInstant instant, boolean exceptionIfFailToDelete) {
public boolean deleteInstantFileIfExists(HoodieInstant instant, boolean throwIfFailed) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in what case do we want to silence the failure? this relates to timeline integrity so we should prefer to fail out loud

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines -271 to +275
Path inFlightCommitFilePath = getInstantFileNamePath(instant.getFileName());
Path commitFilePath = getInstantFileNamePath(instant.getFileName());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to be careful about what commit can be deleted. this API is designed to only delete requested/inflight or empty clean commit, based on the usage. (1 exception is in org.apache.hudi.cli.commands.TestRepairsCommand#testShowFailedCommits where this api is misused for deleting completed commits in tests; we should make separate test helper for that)

We can't delete completed commit instants, which breaks the timeline's integrity. So we should name it properly at the variable as well as the API level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then we should add some doc for this method. inFlightCommitFilePath doesn't represent requested and empty clean instant.

instants,
instant -> ImmutablePair.of(
instant,
metaClient.getActiveTimeline().deleteInstantFileIfExists(instant, false)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the original invocation is ignoreFailure=false; you inverted the flag here by saying exceptionIfFailToDelete=false, which silence the error

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wrong about that. I thought the original logic was the ignoreFailure=false case. Will fix this.

@YannByron
Copy link
Contributor Author

YannByron commented Nov 25, 2022

  • at timeline API level, we should not allow ignoring error; this affects data integrity

i thought there was a case that need to ignore this error. Will correct this.

  • there is another API org.apache.hudi.common.table.timeline.HoodieActiveTimeline#deleteInstantFile(org.apache.hudi.common.table.timeline.HoodieInstant) to be consolidated/dedup'ed

I know that and have did this. But Danny suggests that make this pr force on one question.

  • pls file jira as this touches critical code path, also properly fill the PR template "Impact" and "Risk" sections

file a jira. but after this pr is updated, there is almost no risk and impact.

  • pls help increase UT coverage for critical APIs wherever applicable

the existing UT is enough to cover this improvement.

@YannByron YannByron changed the title [MINOR] move logic for deleting active instant to HoodieActiveTimeline [HUDI-5279] move logic for deleting active instant to HoodieActiveTimeline Nov 25, 2022
@YannByron YannByron requested a review from xushiyan November 25, 2022 13:39
Comment on lines 571 to 578
private void deleteArchivedInstants(HoodieEngineContext context,
HoodieTableMetaClient metaClient,
List<HoodieInstant> instants) {
if (!instants.isEmpty()) {
context.foreach(
instants,
instant -> metaClient.getActiveTimeline().deleteInstantFileIfExists(instant),
Math.min(instants.size(), config.getArchiveDeleteParallelism())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to use a separate method: this method overload the other method, only signature changes that confuses people about which calls which. This is just 1 line invocation. you just call context.foreach() once for the 2 lists together by chaining them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, not found there is another method with same name.

@YannByron
Copy link
Contributor Author

@hudi-bot run azure

@hudi-bot
Copy link
Collaborator

CI report:

Bot commands @hudi-bot supports the following commands:
  • @hudi-bot run azure re-run the last Azure build

@YannByron YannByron merged commit fdce2b8 into apache:master Nov 30, 2022
vamshigv pushed a commit to vamshigv/hudi that referenced this pull request Dec 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

5 participants