-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
stickiness: add stickiness support #1969
Conversation
clientconn.go
Outdated
@@ -1394,6 +1403,12 @@ func (ac *addrConn) getState() connectivity.State { | |||
return ac.state | |||
} | |||
|
|||
func (ac *addrConn) getCurAddr() resolver.Address { | |||
ac.mu.Lock() | |||
defer ac.mu.Unlock() |
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.
Seems like this will be called on the hot path. How about we don't use defer, if that's the case?
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.
Done
picker_wrapper.go
Outdated
@@ -60,6 +70,19 @@ func (bp *pickerWrapper) connectionError() error { | |||
return err | |||
} | |||
|
|||
func (bp *pickerWrapper) updateStickinessMDKey(newKey string) { | |||
bp.stickinessMu.Lock() | |||
if bp.stickinessMDKey != newKey { |
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.
Can stickinessMDKey
be updated on the fly? Currently, it seems like this method is called only during initialization.
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.
Yes, it's updated as part of the service config.
picker_wrapper.go
Outdated
@@ -40,10 +42,18 @@ type pickerWrapper struct { | |||
// The latest connection happened. | |||
connErrMu sync.Mutex | |||
connErr error | |||
|
|||
stickinessMu sync.Mutex | |||
stickinessMDKey string |
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.
If this can change after initialization, how about using atomic.Value
instead of mutex?
Since stickyStore
has a mutex inside of it, we don't need another mutex to protect it.
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.
Done
Documentation/stickiness.md
Outdated
|
||
With load balancer, each RPC pick a different backend based on the load | ||
balancing policy. Stickiness policies try to preserve peers for the duration of | ||
a session. |
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.
Explain this a little more?
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.
Done
picker_wrapper.go
Outdated
|
||
type stickyStore struct { | ||
mu sync.Mutex | ||
store map[string]*stickyStoreEntry |
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.
Can this key not be a string? This key doesn't depend on service config right?
Also, How about instead of using a map we use 10 slices each with it's own mutex and convert the string into an int (without using something as expensive as hashing), and mod the int with 10 and use that slice for it?
One possible way of string to int could be:
a := "some_string"
num := 0
for _, b := range []byte(a){
num += int(b)
}
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.
The key comes from metadata, it has to be string. No hashing should be applied to the stickiness key.
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.
Thanks for the review!
All fixed. PTAL.
picker_wrapper.go
Outdated
@@ -60,6 +70,19 @@ func (bp *pickerWrapper) connectionError() error { | |||
return err | |||
} | |||
|
|||
func (bp *pickerWrapper) updateStickinessMDKey(newKey string) { | |||
bp.stickinessMu.Lock() | |||
if bp.stickinessMDKey != newKey { |
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.
Yes, it's updated as part of the service config.
clientconn.go
Outdated
@@ -1394,6 +1403,12 @@ func (ac *addrConn) getState() connectivity.State { | |||
return ac.state | |||
} | |||
|
|||
func (ac *addrConn) getCurAddr() resolver.Address { | |||
ac.mu.Lock() | |||
defer ac.mu.Unlock() |
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.
Done
picker_wrapper.go
Outdated
|
||
type stickyStore struct { | ||
mu sync.Mutex | ||
store map[string]*stickyStoreEntry |
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.
The key comes from metadata, it has to be string. No hashing should be applied to the stickiness key.
Documentation/stickiness.md
Outdated
|
||
With load balancer, each RPC pick a different backend based on the load | ||
balancing policy. Stickiness policies try to preserve peers for the duration of | ||
a session. |
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.
Done
picker_wrapper.go
Outdated
@@ -40,10 +42,18 @@ type pickerWrapper struct { | |||
// The latest connection happened. | |||
connErrMu sync.Mutex | |||
connErr error | |||
|
|||
stickinessMu sync.Mutex | |||
stickinessMDKey string |
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.
Done
e038967
to
21f4ca0
Compare
Benchmark result for non-sticky RPCs:
|
picker_wrapper.go, line 73 at r4 (raw file):
How about Comments from Reviewable |
picker_wrapper.go, line 80 at r4 (raw file):
Same as above Comments from Reviewable |
stickiness_test.go, line 172 at r4 (raw file):
How about: Comments from Reviewable |
Review status: 0 of 6 files reviewed at latest revision, 3 unresolved discussions. picker_wrapper.go, line 73 at r4 (raw file): Previously, MakMukhi (mmukhi) wrote…
Done. picker_wrapper.go, line 80 at r4 (raw file): Previously, MakMukhi (mmukhi) wrote…
Done. stickiness_test.go, line 172 at r4 (raw file): Previously, MakMukhi (mmukhi) wrote…
Done. Comments from Reviewable |
tests - TestStickyKeyFromContext - TestStickinessEnd2end - service config value is read correctly - TestStickinessChangeMDKey - TestStickinessSwitchingBalancer add doc
- comment for missing field in service config - atomic swap pointer - XOR in test
This reverts commit e8a6e28.
This change is