Skip to content

Consolidate RetrieveSegmentsToReplaceAction into RetrieveUsedSegmentsAction#15699

Merged
AmatyaAvadhanula merged 11 commits intoapache:masterfrom
AmatyaAvadhanula:replace_retrieve_segments_action
Jan 29, 2024
Merged

Consolidate RetrieveSegmentsToReplaceAction into RetrieveUsedSegmentsAction#15699
AmatyaAvadhanula merged 11 commits intoapache:masterfrom
AmatyaAvadhanula:replace_retrieve_segments_action

Conversation

@AmatyaAvadhanula
Copy link
Copy Markdown
Contributor

@AmatyaAvadhanula AmatyaAvadhanula commented Jan 17, 2024

This PR aims to let the original RetrieveUsedSegmentsAction work with REPLACE locks by introducing a boolean flag.
When the task does not hold any REPLACE locks, the behaviour is identical to the existing behaviour.
However, when there are REPLACE locks, only segments that were created before the times corresponding to the versions of the locks will be fetched for their respective intervals.

Using the original action helps with rolling upgrades where the flag is simply ignored when the overlord has not been upgraded.
It also helps eliminate the need for the undocumented parameter introduced in #15430

  • been self-reviewed.
  • added documentation for new or modified features or behaviors.
  • a release note entry in the PR description.
  • added Javadocs for most classes and all non-trivial methods. Linked related entities via Javadoc links.
  • added or updated version, license, or notice information in licenses.yaml
  • added comments explaining the "why" and the intent of the code wherever would not be obvious for an unfamiliar reader.
  • added unit tests or modified existing tests to cover new code paths, ensuring the threshold for code coverage is met.
  • added integration tests.
  • been tested in a test Druid cluster.

@github-actions github-actions Bot added Area - Batch Ingestion Area - MSQ For multi stage queries - https://github.com/apache/druid/issues/12262 labels Jan 17, 2024
@AmatyaAvadhanula AmatyaAvadhanula marked this pull request as ready for review January 19, 2024 10:33
@AmatyaAvadhanula AmatyaAvadhanula changed the title [Do not merge] Verify action segmentListUsed with retrieveSegmentsToReplace Consolidate RetrieveSegmentsToReplaceAction into RetrieveUsedSegmentsAction Jan 19, 2024
Copy link
Copy Markdown
Contributor

@kfaraz kfaraz left a comment

Choose a reason for hiding this comment

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

We should also remove the other task action RetrieveSegmentsToReplaceAction as that is not needed anymore.
A rolling upgrade would upgrade MMs first, so we would not have an issue of firing a task action that the OL doesn't recognize.

// Defaulting to the former behaviour when visibility wasn't explicitly specified for backward compatibility
this.visibility = visibility != null ? visibility : Segments.ONLY_VISIBLE;

this.replace = replace != null ? replace : false;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can this not be determined automatically while running the action? Only tasks with a REPLACE lock would have this as true, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I think this can always be true.
If we need to fetch all the unfiltered segments for a task holding replace locks, we could use a task action client created using a different task that holds no locks.

@Override
public Collection<DataSegment> perform(Task task, TaskActionToolbox toolbox)
{
if (!replace) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cleaner to do:

if (isReplaceTask()) {
  return newMethodWhichDoesTheRightThingForReplaceTask();
} else {
  return retrieveUsedSegments(toolbox);
}

private boolean isReplaceTask() {
   return replace && task.getDatasource().equals(dataSource);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The new method should also have a javadoc saying that it returns a consistent view of segments and why it is needed.

Copy link
Copy Markdown
Contributor Author

@AmatyaAvadhanula AmatyaAvadhanula Jan 20, 2024

Choose a reason for hiding this comment

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

I think the current structure makes it more readable as it is obvious that we are using the old logic whenever possible before trying to filter the segments using the locks.


if (datasourceToReplace != datasourceToRead) {
  return retrieveUsedSegments();
}

Set<ReplaceLock> replaceLocks = fetchReplaceLocksForTask();

if (replaceLocks.isEmpty()) {
  return retrieveUsedSegments()
} 

return retrieveUsedSegmentsCreatedBeforeReplaceVersions(replaceLocks);

Comment on lines +143 to +148
final String supervisorId;
if (task instanceof AbstractBatchSubtask) {
supervisorId = ((AbstractBatchSubtask) task).getSupervisorTaskId();
} else {
supervisorId = task.getId();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For later, can we confirm if this logic is really needed? I think the task action is always fired using the supervisor task ID.

allSegmentsToBeReplaced.addAll(createdAndSegments.getValue());
} else {
for (DataSegment segment : createdAndSegments.getValue()) {
log.info("Ignoring segment[%s] as it has created_date[%s] greater than the REPLACE lock version[%s]",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of logging all segment IDs separately, add them to a set and just log once.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The intent was to keep it verbose with the segment id and created date with the replace version available in each log.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I fear it might end up being too verbose. Better to just log the replace lock version for each interval and point out that anything newer than that would not be considered.
The segment IDs if needed can go in a debug log.

Copy link
Copy Markdown
Contributor

@kfaraz kfaraz left a comment

Choose a reason for hiding this comment

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

Changes look okay, left minor comments and MSQ tests need to be handled.

dataSource,
intervals
));
// Additional check as the task action does not accept empty intervals
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't think this comment is really needed or accurate. The real reason we are not firing a task action if the intervals is empty because we know we would get back an empty result. Why perform an unnecessary round trip?

Comment on lines +1240 to +1243
publishedUsedSegments = context.taskActionClient().submit(new RetrieveUsedSegmentsAction(
dataSource,
intervals
));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

style:

Suggested change
publishedUsedSegments = context.taskActionClient().submit(new RetrieveUsedSegmentsAction(
dataSource,
intervals
));
publishedUsedSegments = context.taskActionClient().submit(
new RetrieveUsedSegmentsAction(dataSource, intervals)
);

return retrieveUsedSegments(toolbox);
}

Map<Interval, Map<String, Set<DataSegment>>> intervalToCreatedToSegments = new HashMap<>();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I recall putting a comment here but can't find it anywhere.
I would prefer it if we moved the code here on down into a new method
retrieveUsedSegmentsForReplace(toolbox, replaceLocks).

@abhishekagarwal87 abhishekagarwal87 added this to the 29.0.0 milestone Jan 29, 2024
@AmatyaAvadhanula AmatyaAvadhanula merged commit 54d0e48 into apache:master Jan 29, 2024
AmatyaAvadhanula added a commit to AmatyaAvadhanula/druid that referenced this pull request Jan 30, 2024
…Action (apache#15699)

Consolidate RetrieveSegmentsToReplaceAction into RetrieveUsedSegmentsAction
LakshSingla pushed a commit that referenced this pull request Jan 30, 2024
…Action (#15699) (#15784)

Consolidate RetrieveSegmentsToReplaceAction into RetrieveUsedSegmentsAction
pagrawal10 pushed a commit to pagrawal10/druid that referenced this pull request Jan 30, 2024
…Action (apache#15699)

Consolidate RetrieveSegmentsToReplaceAction into RetrieveUsedSegmentsAction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area - Batch Ingestion Area - Ingestion Area - MSQ For multi stage queries - https://github.com/apache/druid/issues/12262

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants