Skip to content

HDDS-15839. Implement SCM container ID export manager - #10813

Closed
sarvekshayr wants to merge 12 commits into
apache:masterfrom
sarvekshayr:export-tool-4
Closed

HDDS-15839. Implement SCM container ID export manager#10813
sarvekshayr wants to merge 12 commits into
apache:masterfrom
sarvekshayr:export-tool-4

Conversation

@sarvekshayr

@sarvekshayrsarvekshayr commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Adds the SCM leader-side container ID export worker. Jobs paginate through ContainerManager.getContainerIDs() with lifecycle/health filters, write sharded text files, and pack them into a gzip-compressed TAR archive (or succeed with zero matches and no archive).

ContainerExportManager.java - Async export worker: submit, paginate, shard, TAR append, job tracking.
ExportJob.java - In-memory job state: Id, execution state, and Status (state, total rows, TAR path, error message).
ExportScope.java - Lifecycle and health filter naming for export jobs and archive file names.
ExportFileManager.java - Extended with shard write, archive creation, and failed-job cleanup helpers.
TestContainerExportManager.java - Unit tests for ContainerExportManager.
TestExportFileManager.java - Minor updates for archive path helpers.

Part 4 in splitting HDDS-15496#10673 container ID export.

What is the link to the Apache JIRA

HDDS-15839

How was this patch tested?

Added a new unit test class TestContainerExportManager (no RPC or CLI yet).

@devmadhuudevmadhuu left a comment

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.

Thanks @sarvekshayr for the patch. Largely the PR looks good, just few minor comments.

@szetszwoszetszwo left a comment

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.

@sarvekshayr , thanks for splitting this out. Some general comments

  • Refactor out all the File/Directory related code to a new class ExportFileManager
  • Describe directory layout in ExportFileManager (very important since changing it is an incompatible change)
  • Except for ContainerExportManager, use "Export" instead of "ContainerExport" as the prefix for the classnames

See also the comments inlined.

@szetszwo

Copy link
Copy Markdown
Contributor
  • Refactor out all the File/Directory related code to a new class ExportFileManager
  • Describe directory layout in ExportFileManager (very important since changing it is an incompatible change)

@sarvekshayr , indeed, this PR is also quite big. Let's work on ExportFileManager and directory layout in a separated JIRA.

@sarvekshayr

Copy link
Copy Markdown
ContributorAuthor
  • Refactor out all the File/Directory related code to a new class ExportFileManager
  • Describe directory layout in ExportFileManager (very important since changing it is an incompatible change)

@sarvekshayr , indeed, this PR is also quite big. Let's work on ExportFileManager and directory layout in a separated JIRA.

Created HDDS-15935.

@devmadhuudevmadhuu left a comment

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.

Thanks @sarvekshayr for improving the patch. Largely LGTM +1. Just a nit for rare case. Pls check.

@sarvekshayr
sarvekshayr marked this pull request as ready for review July 22, 2026 17:06

@devmadhuudevmadhuu left a comment

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.

Thanks @sarvekshayr for improving the patch. LGTM +1

@szetszwo

Copy link
Copy Markdown
Contributor

Created HDDS-15935.

@sarvekshayr , are we going to do HDDS-15935 first and then this? Is it the case?

@sarvekshayr

Copy link
Copy Markdown
ContributorAuthor

Created HDDS-15935.

@sarvekshayr , are we going to do HDDS-15935 first and then this? Is it the case?

Not in this PR. HDDS-15935 will land in a follow-up PR after this one is merged.

@ArafatKhan2198ArafatKhan2198 left a comment

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.

Thanks for the patch @sarvekshayr mostly looks good!
Some comments you can consider.
Please let me know if I am missing out on something.

@szetszwoszetszwo left a comment

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.

Not in this PR. HDDS-15935 will land in a follow-up PR after this one is merged.

It is fine only if this PR does not create any files.

Otherwise, we will need the disk layout description (i.e. HDDS-15935) first.

@szetszwoszetszwo left a comment

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.

@sarvekshayr , Thanks for the update! Please see some quick comments inlined. BTW, the role of ContainerExportManager and ExportFileManager should be:

  • ContainerExportManager: manage jobs
  • ExportFileManager: manage files

@szetszwoszetszwo left a comment

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.

@sarvekshayr , thanks for the update! Please see the comments inlined.

BTW, before submitting a PR, please review it yourself first. If there are unused methods/code, remove them.

@szetszwoszetszwo left a comment

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.

@sarvekshayr , thanks for the update!

This change is still too big. I tried to review this multiple times but failed due to the size of the PR. (People usually cannot spend a whole day reviewing a single PR. They have other things to do. Recall the point of "Rapid Feedback" in the Google AI Overview on Multiple Small Changes.)

Please split it into two PRs.

  • Do not mix simple changes with complicated changes. In this case, the metrics can be added later. Tried to limit the PR size to < 30KB. The current PR size is 57KB.
% git diff apache/master...sarvekshayr/export-tool-4 > a.patch
% ls -lh a.patch
-rw-r--r--@ 1 szetszwo staff 57K Aug 13 20:48 a.patch
  • The test is only 15KB. It seems not enough compared to the code size (~40KB). Try using AI to generate tests.
% ls -lh hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/export/TestContainerExportManager.java
-rw-r--r--@ 1 szetszwo staff 15K Aug 13 20:51 hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/export/TestContainerExportManager.java
  • Do not add short methods which are used only once.

See also the comments inlined and also https://issues.apache.org/jira/secure/attachment/13083920/10813_review.patch. Sorry that I only reviewed a part of the PR due to time limit.

@sarvekshayr

Copy link
Copy Markdown
ContributorAuthor

Thanks @szetszwo for the review!

I agree that this PR became quite large since it pulls in all the functions for ContainerExportManager. To make reviewing easier, I propose splitting it into smaller, logical PRs as outlined below:

  • PR 1: Minimal end-to-end export on SCM leader - One export job can run on the SCM leader, write shards, produce a tar (or succeed with zero matches), and expose basic status.
  • PR 2: Export limits, request sizing, and shared constants.
  • PR 3: Terminal job retention and archive eviction

If this plan looks good, I’ll start refactoring and update this PR accordingly.

@szetszwo

Copy link
Copy Markdown
Contributor

If this plan looks good, I’ll start refactoring and update this PR accordingly.

Sure, the plan looks great!

A rule of thumb is that simple change PR (renaming, adding conf/metrics, simple refactoring, etc.) can be larger while a complicated PR (logic changes, new code, non-trivial bug fixes, etc.) should be as small as possible. We want to make a complicated problem obvious and easy to be understood.

@szetszwoszetszwo left a comment

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.

@sarvekshayr , thanks for the update! The current change is still quite large and also has synchronization problems (there are many synchronized methods but calling them separately will not be synchronized correctly.)

Let's do something simple first:

  • add ExportJob but not ContainerExportManager
  • change ExportFileManager
  • rename "shard" to "part"
  • rename "pageSize" to "batchSize"
  • rename "timestamp" to "jobStartTime" .

Comment on lines +66 to +67
private final int shardSize;
private final int pageSize;

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.

If I understand correctly, "shard" and "page" may not be the best names here since

  • shard: a specific name for horizontal partition in a database but here we don't have a database.
  • pageSize: it is actually a batchSize since the size information is forgotten after the file is written.

Google suggested to call the sub-files "parts".

Image


containerExportManager = new ContainerExportManager(
getScmId(), containerManager, this::checkLeader, conf);
containerExportManager.start();

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.

containerExportManager.start() should be called in StorageContainerManager.start() but not the constructor.

}

String shardFileName(int partIndex) {
return String.format("container-ids_%s_%s_part%03d.txt",

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.

Indeed, you are already using "part" -- don't use different words for the same thing.

Comment on lines +88 to +114
/**
* Snapshot of export progress returned to callers. Reads live fields from the enclosing job.
*/
public final class Status {
private Status() {
}

public Id getId() {
return id;
}

public ExecutionState getExecutionState() {
return ExportJob.this.getExecutionState();
}

public long getTotalRows() {
return ExportJob.this.getTotalRows();
}

public String getTarPath() {
return ExportJob.this.getTarPath();
}

public String getErrorMessage() {
return ExportJob.this.getErrorMessage();
}
}

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.

Remove State for now. It is currently not used and the synchronization is incorrect. Let's add it later.

private final ContainerID startContainerId;
private final int pageSize;
private final int shardSize;
private String tarPath;

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.

Why tarPath is not final? Explain how could it be changed?

@sarvekshayr

Copy link
Copy Markdown
ContributorAuthor

Raised #11052 with simple changes as suggested. Last few comments (synchronization, renaming, tarPath) will be addressed in follow-up PRs.

@szetszwo

szetszwo commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

... has synchronization problems (there are many synchronized methods but calling them separately will not be synchronized correctly.)

@sarvekshayr , synchronization can be done by using a ReentrantReadWriteLock:

  • Whenever a thread submitting/running a job, acquire the write lock and check Job id.
  • When other threads getting the status, acquire the read lock.
  • Since we are using ReentrantReadWriteLock, remove synchronized from all the methods.

BTW, let's close this and continue with a new PR. This PR is already very long.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@sarvekshayr@szetszwo@devmadhuu@ArafatKhan2198