-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[fix] [txn] [PIP-160] Avoid timing task burdens the ledger thread and leads to an avalanche #16679
Conversation
… leads to an avalanche
scheduledFuture = scheduledExecutorService.schedule(() -> trigFlush(false, true), | ||
batchedWriteMaxDelayInMillis, TimeUnit.MICROSECONDS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scheduledFuture = scheduledExecutorService.schedule(() -> trigFlush(false, true), | |
batchedWriteMaxDelayInMillis, TimeUnit.MICROSECONDS); | |
scheduledFuture = scheduledExecutorService.schedule(() -> trigFlush(false, true), | |
batchedWriteMaxDelayInMillis, TimeUnit.MILLISECONDS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Already fixed.
} | ||
}).when(managedLedger).asyncAddEntry(Mockito.any(ByteBuf.class), Mockito.any(), Mockito.any()); | ||
// Start tests. | ||
TxnLogBufferedWriter txnLogBufferedWriter = new TxnLogBufferedWriter<>(managedLedger, orderedExecutor, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Close the write after test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Already fixed.
I can't understand this PR. I'm not sure I understand the nature of the context in this PR - would love a good brief on that - but could it be that |
Hi @asafm
Yes, I added more descriptions in
This change can only avoid the task accumulation in TxnLogBufferedWriter caused by too many scheduled tasks but cannot improve the write performance of Managed Ledger. I added more descriptions in Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check the failed test
org.apache.pulsar.transaction.coordinator.impl.TxnLogBufferedWriterTest ► testFlushThresholds
Failed test found in:
TEST-org.apache.pulsar.transaction.coordinator.impl.TxnLogBufferedWriterTest.xml
Error:
java.lang.AssertionError: expected [100] but found [101]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After checking more details, we missed a part. If we flushed a batch, the next schedule should start by the last flush time + batch delay.
After flush a batch, the task container is empty, so there is no need to check whether the first task needs to be executed earlier than |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
The flaky Test has been fixed. but the scheduled task timing is not as precise as I remember, I will look at it later |
/pulsarbot run-failure-checks |
/pulsarbot run-failure-checks |
Master Issue: #15370
Motivation
see #15370
Modifications
Managed Ledger I/O thread gets busier and busier.
In origin implementation,
TxnLogBufferedWriter
has two thread pools:ExecutorService singleThreadExecutorForWrite
is A single-threaded actuator, used to perform Managed Ledger I/O operations. Includes the following tasks:internalAsyncAddData
Each execution of theasyncAddData
adds a task.doFlush
The execution oftrigFlush
sometimes add a task, and there is also a scheduled task that adds tasks.ScheduledExecutorService scheduledExecutorService
is used to periodically adddoFlush
tasks to thesingleThreadExecutorForWrite
, whether thesingleThreadExecutorForWrite
is idle or not.If
singleThreadExecutorForWrite
is busy for a period of time,scheduledExecutorService
will keep addingdoFlush
tasks during that period. ThensingleThreadExecutorForWrite
will be busy with the newly addeddoFlush
tasks and allocate fewer resources tointernalAsyncAddData
whilescheduledExecutorService
is addingdoFlush
tasks, which will causesingleThreadExecutorForWrite
to accumulate more and more tasks, even if that thedoFlush
task appended byscheduledExecutorService
possible only triggers the check and does nothing else. The net result is thatsingleThreadExecutorForWrite
gets busier and busier.Imprecise timing task
If new data is added immediately after a scheduled task is executed, the data cannot be flushed in the next scheduled task. Aka. we set the max delay time to 1 min, the scheduled tasks and new data tasks are executed in the following sequence:
In the step-4, the flush task will not flush the data to the bookie, because the result of expression
System.currentTimeMillis() - firstAsyncAddArgs.addedTime >= batchedWriteMaxDelayInMillis
isfalse
, this data will actually flushed at next scheduled task12:00:03.000
Changes:
Managed Ledger I/O thread gets busier and busier.
Since all C tasks are executed in the same thread, we can change that "after a scheduled task is executed, then add the next one". This reduces the density of
doFlush trig by timer
task execution, thereby somewhat losing timing accuracy (the original implementation was not completely accurate either).This change can only avoid the task accumulation in
TxnLogBufferedWriter
caused by too many scheduled tasks, but cannot improve the write performance of Managed Ledger.Imprecise timing task
Flush triggered by the scheduled task no longer determines whether the time of the first node reaches the condition. To avoid imprecise scheduled task execution time, the maximum delay time is still checked and flushed in the Flush task triggered by the
asyncAddData
.Documentation
doc-required
doc-not-needed
doc
doc-complete