Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use SingleThreadExecutor for OrderedExecutor and drainTo() tasks into local array #3546

Merged
merged 10 commits into from
Oct 20, 2022

Conversation

merlimat
Copy link
Contributor

Motivation

OrderedExecutor is used extensively throughout the BK codebase and its performance is critical when there are many small entries.

In the past we have experimented with different BlockingQueue backends inside the JDK default ThreadPoolExecutor implementation.

The main problem with ThreadPoolExecutor is that is not using the drainTo() to avoid contention, because it's not making any assumptions on the queue type. If we assume an array based queue (like ArrayBlockingQueue), then the drainTo() makes it much more efficient.

A single executor with 16 thread submitting tasks can now process 46M tasks/s

@zymap
Copy link
Member

zymap commented Oct 18, 2022

Error: Failures:
Error: org.apache.bookkeeper.common.util.TestSingleThreadExecutor.testShutdownNow
Error: Run 1: TestSingleThreadExecutor.testShutdownNow:183 expected:<2> but was:<0>
Error: Run 2: TestSingleThreadExecutor.testShutdownNow:183 expected:<2> but was:<0>
Error: Run 3: TestSingleThreadExecutor.testShutdownNow:183 expected:<2> but was:<0>

There are some failure tests related to this change.

return thread.getTaskCount();
}
});
if (thread instanceof ThreadPoolExecutor) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The thread created by createSingleThreadExecutor is not a subclass of ThreadPoolExecutor, which means we will lose the following thread metrics.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Also, I think there is an opportunity to add more stats around rejected & failed tasks. It would be very useful to see these in the charts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hangc0276 Fixed, PTAL.

@merlimat
Copy link
Contributor Author

Error: Failures: Error: org.apache.bookkeeper.common.util.TestSingleThreadExecutor.testShutdownNow Error: Run 1: TestSingleThreadExecutor.testShutdownNow:183 expected:<2> but was:<0> Error: Run 2: TestSingleThreadExecutor.testShutdownNow:183 expected:<2> but was:<0> Error: Run 3: TestSingleThreadExecutor.testShutdownNow:183 expected:<2> but was:<0>

There are some failure tests related to this change.

@zymap Fixed the test, PTAL

@hangc0276
Copy link
Contributor

Error: Failures:
Error: org.apache.bookkeeper.common.util.TestSingleThreadExecutor.testRejectWhenQueueIsFull
Error: Run 1: TestSingleThreadExecutor.testRejectWhenQueueIsFull:100 should have rejected the task
Error: Run 2: TestSingleThreadExecutor.testRejectWhenQueueIsFull:100 should have rejected the task
Error: Run 3: TestSingleThreadExecutor.testRejectWhenQueueIsFull:100 should have rejected the task
[INFO]
Error: org.apache.bookkeeper.common.util.TestSingleThreadExecutor.testSimple
Error: Run 1: TestSingleThreadExecutor.testSimple:65 expected:<11> but was:<10>
Error: Run 2: TestSingleThreadExecutor.testSimple:65 expected:<11> but was:<10>
Error: Run 3: TestSingleThreadExecutor.testSimple:65 expected:<11> but was:<10>
[INFO]
Error: org.apache.bookkeeper.common.util.TestSingleThreadExecutor.testTasksWithNPE
Error: Run 1: TestSingleThreadExecutor.testTasksWithNPE:265 expected:<1> but was:<0>
Error: Run 2: TestSingleThreadExecutor.testTasksWithNPE:265 expected:<1> but was:<0>
Error: Run 3: TestSingleThreadExecutor.testTasksWithNPE:265 expected:<1> but was:<0>
[INFO]
Warning: Flakes:
Warning: org.apache.bookkeeper.common.util.TestSingleThreadExecutor.testTasksWithException
Error: Run 1: TestSingleThreadExecutor.testTasksWithException:240 expected:<1> but was:<0>

@merlimat Please take a look at the above-failed tests.

Copy link
Contributor

@hangc0276 hangc0276 left a comment

Choose a reason for hiding this comment

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

Great job!

/**
* Unit test for {@link SingleThreadExecutor}.
*/
public class TestSingleThreadExecutor {
Copy link
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 test to validate the SingleThreadExecutor metrics?

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've added assertions to verify the values of the counters. Do you mean to read the gauges out of the StatsLogger?

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

Successfully merging this pull request may close these issues.

None yet

3 participants