-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Auto-tuning DotNetty batching + removing scheduler from batching system #4685
Auto-tuning DotNetty batching + removing scheduler from batching system #4685
Conversation
How It WorksThe The algorithm is designed to capture flushes that occur in rapid succession and group them together in order to lower the total number of system calls to the socket, which improves average throughput and decreases CPU utilization. The flushes are batched together when:
The flushes are allowed to pass and write out to the socket when:
In the third case, we don't use a time-based delay to flush the socket - instead the "flush" call is simply added to the same event queue where all of the read and write events are. It works identically to an actor's mailbox. All of the writes queued up prior to that event get flushed together. |
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.
LGTM - just left minor note and a question about flushing while reading is in process
@@ -2,7 +2,7 @@ | |||
<PropertyGroup> | |||
<Copyright>Copyright © 2013-2020 Akka.NET Team</Copyright> | |||
<Authors>Akka.NET Team</Authors> | |||
<VersionPrefix>1.4.13</VersionPrefix> | |||
<VersionPrefix>1.4.14</VersionPrefix> |
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.
I guess this should not be changed in this PR, it's just build,cmd
updated this file when was running locally?
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.
That's correct
// we only need to flush if we reach the explicitFlushAfterFlushes limit. | ||
if (++_flushPendingCount == ExplicitFlushAfterFlushes) | ||
{ | ||
FlushNow(context); |
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.
So when reading is complete we will flush in ChannelReadComplete
anyway. But we are trying to flush right here if there are too many flushes are pending? Are we able to flush while reading is in process? Or this is safe?
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.
So if a read is sitting in the channel pipeline right now we assume it means that some data is being read by the current application and that might, presumably, be used to produce a response right away - we're trying to batch those writes together into as few flushes as possible and when the read "completes" (we've finished reading all of the data currently inside the buffer) it's safe to flush any writes that are currently pending. This helps reduce latency in lower traffic system AND increases throughput in higher traffic systems.
Ported the
FlushConsolidationHandler
from Netty and used it to auto-tune batching inside Akka.Remote without having to set explicit thresholds and without having to rely on theIScheduler
.This accomplishes:
akka.remote.dot-netty.tcp.batching
- this is now handled automatically by theFlushConsolidationHandler
.close #4636
close #4563
We still have some more work to do optimizing the
DedicatedThreadPool
to scale down automatically, but this eliminates most of the CPU noise coming from DotNetty.