-
Notifications
You must be signed in to change notification settings - Fork 623
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
Shard awareness extension for Scylla #1206
Conversation
conn_test.go
Outdated
@@ -828,14 +828,19 @@ func TestFrameHeaderObserver(t *testing.T) { | |||
|
|||
frames := observer.getFrames() | |||
|
|||
if len(frames) != 2 { | |||
if len(frames) != 3 { | |||
t.Fatalf("Expected to receive 2 frames, instead received %d", len(frames)) |
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.
Do you need to adjust this message now also from 2 frames
into 3 frames
?
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 protocol specifies an additional options query to discover the sharding info which cannot be statically read once since it's a runtime connection property. See the Conn::startup method. Afaik the test then needs to be accommodated. Is this the wrong way to verify this? If there is a better please let me know I am open to suggestions.
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.
Ouch @JvGinkel I read your message too loosely it seems.
I will correct the message. Good catch!
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, there are a few nits with the code itself, but I have some reservations about merging all of it in the current form. The issue is clearly with the fact that it's an addition to include a different SERVER project's properties. I'm definitely not against supporting multiple endpoints, but something in the way it is organised now rubs me the wrong way.
I would probably ask for 2 separate PRs: one for the refactored connPicker
implementation, and another for scylla support. But I would like to see the Scylla support as clearly separated, like maybe using "backends" module, so that main thing is used as a common base (which is, clearly, C*), and then additional backends (like Scylla) do their additional/different implementations.
CC @Zariel
type DefaultConnPicker struct { | ||
conns []*Conn | ||
pos uint32 | ||
size int |
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'd use an unsigned int variant for the size.
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.
It's very viral. This property is threaded through the code and it makes sense to have them as uint
but perhaps not in this patch?
} | ||
|
||
func NewDefaultConnPicker(size int) *DefaultConnPicker { | ||
return &DefaultConnPicker{ |
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.
check for size to be non-zero to avoid errors?
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 can check it here and return an error. If so what do we do then, panic or default to something?
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.
There is no real infrastructure available to handle errors in this. It all relies on the config defaulting to 2. We can change the assumptions but I'd rather not in a patch that is about something else.
What do you think?
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 panic here is fine.
connpicker.go
Outdated
|
||
for i, candidate := range p.conns { | ||
if candidate == conn { | ||
p.conns[i] = conn |
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.
p.conns[i] == nil
?
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.
p.conns[i] = nil
perhaps? I think we should maybe eve resize it what do you think?
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 have set it to nil now. We can change it if you prefer but the rest of the code works guards against nil.
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.
nah, nil is fine. That's exactly what I meant :-)
} | ||
|
||
func (p *DefaultConnPicker) Pick(token) *Conn { | ||
pos := int(atomic.AddUint32(&p.pos, 1) - 1) |
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 sure the initial reason for this, but would you mind just reading atomically directly?
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.
This keeps track of the current position in the conns list. I think it was always like this to step to the next connection in one atomic go.
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.
right, ok
policies.go
Outdated
} | ||
|
||
func (host selectedHost) Info() *HostInfo { | ||
return (*HostInfo)(host.info) |
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.
probably no need to cast here
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.
Ah, thx!
About your major comment @alourie I would also want to isolate and modularize it more but when we implemented this we saw now real option without major refactoring which felt very invasive for such a relatively small patch. It depends of course on what you mean with this backends module? A factory struct that knows how to instantiate backends? I will try to address your minor issues asap, thanks for noticing. Nitpicks accumulate so it's good to catch them early! |
@dahankzter I don't know what's the best way to implement backends, for now, would need to wait until @Zariel has an opinion. Maybe in the next major API change. But splitting this into 2 PRs should not be complicated, no? The connection picker and the Scylla's implementation are quite separate, so I'd assume it would be possible to do. |
We can probably split them up but the assignment of the picker to use is dynamic so at some point the code will blend. There are basically 2 reasons for the code being as is today.
That's it really we can make any sort of bootstrapping otherwise if we don't want 2. |
Hi @alourie, cc @dahankzter |
This is an extension to tokenAwareHostPolicy supported by the Scylla 2.3 and onwards. It allows the driver to select a connection to shard on a host based on token. The protocol extension spec is available at [1]. [1] https://github.com/scylladb/scylla/blob/master/docs/protocol-extensions.md Co-authored-by: Michał Matczuk <[email protected]>
👍 |
This PR brings shard awareness to the token aware policy for Scylla servers version 2.3 or later.
This is done by implementing the Scylla protocol extension mechanism as as defined by:
https://github.com/scylladb/scylla/blob/master/docs/protocol-extensions.md
The impact for Scylla users is significant improvement in performance while still maintaining the original performance for Cassandra users.
Both latency and throughput are greatly improved but especially latency can see an order of magnitude improvement.
No config is needed for the user to benefit from this patch, the driver will discover the sharding support on its own.