-
Notifications
You must be signed in to change notification settings - Fork 702
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
client struct: lazy init components and optimize struct layout #1405
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## unstable #1405 +/- ##
============================================
- Coverage 70.81% 70.79% -0.02%
============================================
Files 118 119 +1
Lines 63561 64728 +1167
============================================
+ Hits 45010 45826 +816
- Misses 18551 18902 +351
|
Amazing! |
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.
Very good! It's a large diff but most of the changed lines are trivial changes. I can't verify everything so I have to trust you and the tests for the correctness.
I noticed in many helper functions, we're using these client sub-structs, for example c->mstate->something
, without checking that c->mstate
exists. It should always exist in these cases so it's not an error, but would it make sense to add serverAssert(c->mstate != NULL)
in all these places?
If we have code coverage by tests, we will find these errors anyway, so IMHO it doens't matter too match if it's a null-pointer crash or an assert. What is your reasoning about this?
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.
Just a few nits now.
b84c52d
to
b4755cb
Compare
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 think the overall change looks O.K, but some cases are not 100% trivial IMO and the change impacts almost all logical flows. I would suggest we run the daily tests to verify this change.
} | ||
|
||
void initClientReplicationData(client *c) { | ||
if (c->repl_data) return; |
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.
Not that I see a real concern here, but we might think this should have been under assert check which would have forced the user to make sure he freeClientReplicationData before init again (if that case ever exists)
pubsubUnsubscribeShardAllChannels(c, 0); | ||
pubsubUnsubscribeAllPatterns(c, 0); | ||
unmarkClientAsPubSub(c); | ||
freeClientPubSubData(c); |
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 in this case we perform the actions of freeClient (eg all the dictReleases) when we unlink the client. Not sure it is problematic, but it is a change in order which is very basic.
Signed-off-by: Uri Yagelnik <[email protected]>
Signed-off-by: Uri Yagelnik <[email protected]>
Co-authored-by: Viktor Söderqvist <[email protected]> Signed-off-by: uriyage <[email protected]>
Co-authored-by: Viktor Söderqvist <[email protected]> Signed-off-by: uriyage <[email protected]>
Co-authored-by: Viktor Söderqvist <[email protected]> Signed-off-by: uriyage <[email protected]>
Signed-off-by: Uri Yagelnik <[email protected]>
b4755cb
to
d4ebb91
Compare
Signed-off-by: Uri Yagelnik <[email protected]>
Refactor client structure to use modular data components
Current State
The client structure allocates memory for replication / pubsub / multi-keys / module / blocked data for every client, despite these features being used by only a small subset of clients. In addition the current field layout in the client struct is suboptimal, with poor alignment and unnecessary padding between fields, leading to a larger than necessary memory footprint of 896 bytes per client. Furthermore, fields that are frequently accessed together during operations are scattered throughout the struct, resulting in poor cache locality.
This PR's Change
Memory Layout Optimization:
Additional changes:
mstate
structKey Benefits
Performance Impact
Tested with 650 clients and 512 bytes values.
Single Thread Performance
8 IO Threads Performance
Pipeline Performance (3M keys)
Observations:
Related issue:#761