-
Notifications
You must be signed in to change notification settings - Fork 58
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
Identify slow points in invocation path #465
Comments
@myronkscott suspects that the reason why waiting for the This also implies that we should investigate if the client<->server batching can benefit any further from some of the ideas applied in our recent active<->passive batching. |
The previous results should be taken with a grain of salt since I realized that they were running on concurrency key 0. I changed them to 1 and got some numbers which look a bit better (since running on key 0 causes a lot of pipeline flush messages which cloud the image). Single-server:
2-server:
Overall cost of adding a passive:
Overall cost of waiting for
The main question still remains: Why does adding a passive increase |
A clear hot-point is There are also some message decoding operations around there but that is a secondary investigation. @myronkscott suspects that the added cost in this method is related to creating the replicated message (per-passive). If so, is it possible to push this off to the batching mechanism for the group channel or the Note that the lion's share of the path is most likely in the |
It seems like the expensive part is in Digging further into that, we spend 66% of that time in This makes sense, and we might want to look into optimizing that method, at some point, but this is so many levels deep that it is a very thin sliver of the total time. I am going to consider this part of the investigation done with this conclusion: Investigate optimization of On to the next part of this investigation, which is looking at activity on the This is the problem I had initially suspected was still somewhere in the stack: blocking active activity on passive replication for non-lifecycle operations. Lifecycle operations (specifically The only thing which needs to block on the passive acknowledgements, in the invoke case, is the sending of the same acks back to the client. That is, we don't need to block on passive To illustrate this further, it is perfectly acceptable for the active or the passive to be any number of invokes ahead of the rest of the stripe so long as the client isn't told about
Actually implementing these ideas will be a bit tricky, and potentially ugly, since the thread which delivers the last required ack will be the one which sends the ack message back to the client. The active->client message batching will hopefully mitigate this (so that we still have a specific thread doing the serialize+send) and, if not, we should be able to modify it to do so. |
Looking at the profile, we do often see stacks where the
What is interesting is that both of these are called from This is the extraneous case mentioned in the previous comment (we don't need to wait for the |
We need to improve the overall performance of the system (especially in the case of multi-server stripes). This requires measuring the current cost of these operations so we have some guidance on where to drill down further.
For these initial numbers, I created a single-client test which sends a sequence of 10000 invokes which do effectively nothing (but manually requesting replication - implicit replication disabled), measuring the average time it takes from before the send to when the
RECEIVED
ack returns to when theCOMPLETED
orRETIRED
ack returns (did 10000 runs of each, interleaved to avoid skew due to trends over time). This was then tested on a single-server stripe versus a 2-server stripe. NOTE: Client and server(s) run on the same machine (avoids network overhead and this test isn't CPU heavy, just a measure of total path length).Each run produced an average of the various ack timings for all configurations. I ran 3 sets and averaged the corresponding results (there was relatively little variability between them).
Single-server:
RECEIVED
toCOMPLETED
: 25% longerRECEIVED
toRETIRED
: 54% longer2-server:
*
RECEIVED
toCOMPLETED
: 77% longer*
RECEIVED
toRETIRED
: 177% longerOverall cost of adding a passive:
*
RECEIVED
when waiting forCOMPLETED
: 9% longer*
RECEIVED
when waiting forRETIRED
: 13% longer*
COMPLETED
: 55% longer*
RETIRED
: 104% longerOverall cost of waiting for
RETIRED
(above just waiting forCOMPLETED
):RECEIVED
: 5%COMPLETED
: 30%RECEIVED
: 9%COMPLETED
: 70%Oddities:
RETIRED
instead ofCOMPLETED
made the time untilRECEIVED
arrived take longer, which wasn't expected.Consistencies with expectations:
RETIRED
, on the passive, effectively doubles the path-length (since the manual replication means the passive can only start after the active has mostly run the message) so the 70% overhead is believable. Single-server cost of 30% is believable since it only adds another invoke, not another network round-trip.RECEIVED
is roughly 10% more expensive when a passive is added (since this means waiting for the message to be replicated).Next steps in investigation:
RETIRED
versusCOMPLETED
changes how long it takes until theRECEIVED
arrives (this should be purely client-side).COMPLETED
cost so much more thanRECEIVED
(since they should both be effectively no-ops with a network message).The text was updated successfully, but these errors were encountered: