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
Add rack aware round-robin host policy #1565
base: master
Are you sure you want to change the base?
Conversation
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.
Thank you for the pull request!
I'm not sure whether we should add every possible policy to gocql. That said, it's not really possible to test policies that live out of tree, so we could probably add this one. But even better would be to change gocql so that external policies could easily be testable.
With the RackAwareRRHostPolicy used as a fallback in TokenAwareHostPolicy, we first select replica from local rack and then fall back to replica from other nodes regardless of whether the replica is in local or remote datacenter. Shouldn't we prefer replicas in order local rack, local DC, remote DC similar to when the policy is used without the TokenAwareHostPolicy?
s.mu.RUnlock() | ||
|
||
q.metrics = &queryMetrics{m: make(map[string]*hostMetrics)} | ||
q.spec = &nonSpeculativeExecution |
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.
Simple q.spec = NonSpeculativeExecution{}
should work here, right?
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 does work here, I just wanted to avoid possible allocation. Not sure if the compiler optimises it out.
That would be preferable, however interface HostSelectionPolicy defines only |
I'm still thinking about this. Technically, we could add an interface like type IsRackLocaler interface {
// IsRackLocal returns true if the host is rack local.
IsRackLocal(host *HostInfo) bool
} that the type HostDistancer interface {
// HostDistance returns an integer specifying how far a host is from the client.
// The value is used to prioritize closer hosts during host selection.
// For example this could be:
// 0 - local rack, 1 - local DC, 2 - remote DC
// or:
// 0 - local DC, 2 - remote DC
HostDistance(host *HostInfo) uint
} and the token aware policy could group by the distance? |
Summary
When Cassandra is provisioned in a cloud environment, in such a way that nodes are spread across multiple availability zones, it is more const effective to query nodes in the same availability zone. Currently
gocql
provides DC-aware round-robin host policy, but it does not respect availability zone. This PR introduces rack-aware round-robin policy that prefers nodes in the same rack, if there are no nodes in the same rack then nodes from the same datacenter are preferred.Usage Guidelines
eu-central-1c
becomes datacentereu-central
and rack1c
;us-central1-a
becomes datacenterus-central1
and racka
;For maximum efficiency we recommend using this policy as a fallback for token aware host policy as follows:
Note that the token-aware policy uses the rack-aware policy to determine if a host is local. Only hosts from the same rack are considered to be local by the rack-aware policy. Non-local replica fallback is enabled to ensure that the token-aware policy still connects to a host that has a replica, even when there are no replicas in the same rack, otherwise decision making would have been handed over to the rack-aware policy that would connect to an arbitrary host from the same datacenter.