Skip to content

Flink: Avoid unnecessary TableLoader.loadTable() in IcebergCommitter subtasks > 0#17251

Open
Guosmilesmile wants to merge 3 commits into
apache:mainfrom
Guosmilesmile:reduce_tableloader_load
Open

Flink: Avoid unnecessary TableLoader.loadTable() in IcebergCommitter subtasks > 0#17251
Guosmilesmile wants to merge 3 commits into
apache:mainfrom
Guosmilesmile:reduce_tableloader_load

Conversation

@Guosmilesmile

Copy link
Copy Markdown
Contributor

Closes #17140

IcebergSink#addPreCommitTopology uses a .global() shuffle to force all committables to subtask 0 of the downstream committer operator, so that commits only happen on a single subtask.

Even though only subtask 0 will ever receive a CommitRequest, every committer subtask still eagerly loads the Iceberg table and creates a worker thread pool in its constructor.

This pr add code to avoid unnecessary TableLoader.loadTable() in IcebergCommitter subtasks > 0 .

@mxm mxm 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 @Guosmilesmile!

Comment on lines +1162 to +1188
@TestTemplate
public void testCommitterOnSubtaskZeroLoadsTable() throws Exception {
TableLoader spyLoader = spy(tableLoader);
IcebergFilesCommitterMetrics metric = mock(IcebergFilesCommitterMetrics.class);
IcebergCommitter committer =
new IcebergCommitter(
spyLoader, branch, Collections.emptyMap(), false, 10, "sinkId", metric, false, 0);

verify(spyLoader).open();
verify(spyLoader).loadTable();

committer.close();
}

@TestTemplate
public void testCommitterOnNonZeroSubtaskSkipsTableLoad() throws Exception {
TableLoader spyLoader = spy(tableLoader);
IcebergFilesCommitterMetrics metric = mock(IcebergFilesCommitterMetrics.class);
IcebergCommitter committer =
new IcebergCommitter(
spyLoader, branch, Collections.emptyMap(), false, 10, "sinkId", metric, false, 1);

verify(spyLoader, never()).open();
verify(spyLoader, never()).loadTable();

committer.close();
}

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 would prefer more of an end-to-end test, e.g. using a Minicluster or a TestHarness which utilizes the entire path. This is a critical code path and a simple unit test IMHO is not enough.

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.

Make sense. Change ut to use TestHarness

Comment on lines +102 to +114
if (subtaskId == 0) {
if (!tableLoader.isOpen()) {
tableLoader.open();
}

this.table = tableLoader.loadTable();
this.maxContinuousEmptyCommits =
PropertyUtil.propertyAsInt(table.properties(), MAX_CONTINUOUS_EMPTY_COMMITS, 10);
Preconditions.checkArgument(
maxContinuousEmptyCommits > 0, MAX_CONTINUOUS_EMPTY_COMMITS + " must be positive");
this.workerPool =
ThreadPools.newFixedThreadPool(
"iceberg-committer-pool-" + table.name() + "-" + sinkId, workerPoolSize);

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 we add a comment why we are only initializing for subtaskId == 0?

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.

Right, add comment on it.

@mxm mxm 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.

LGTM. Thanks @Guosmilesmile!

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flink IcebergSink committer calls TableLoader.loadTable() per subtask, fanning out catalog loads at startup

2 participants