Skip to content

Commit

Permalink
Fix selection of host by token (apache#1405)
Browse files Browse the repository at this point in the history
We've seen increased per-query latency after upgrading to latest gocql.
This commit fixes the latency issue for us.

This partially reverts 7b17705. There
were multiple unrelated changes in that commit. The relevant part of
that commit's description is:

    Fix finding the correct token in the token ring for host selection.

Unfortunately that description does not contain the details of the issue
it was aimed to fix.

The change in 7b17705 also made the two
binary search implementations (tokenRingReplicas.replicasFor and
tokenRing.GetHostForToken) inconsistent, reverting the change fixed this
discrepancy as well.

The token values returned in system.peers and system.local tables are
ends of ranges that the nodes are responsible for[1], so we never need
to rollunder.

When searching for a node responsible for token X (computed from
partition key), we need to find hostTokens with end token Y with the
lowest value such that Y >= X. In case X is larger than the largest
end token value in tokenRingReplicas, we wrap the ring and the node with
the lowest token is responsible (i.e. the hostTokens at index 0).

[1] https://docs.datastax.com/en/dse/6.7/dse-arch/datastax_enterprise/dbArch/archAboutDataDistribute.html
  • Loading branch information
martin-sucha authored Feb 27, 2020
1 parent e5c8c1f commit 9b18429
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 12 deletions.
4 changes: 2 additions & 2 deletions policies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ func TestHostPolicy_TokenAware_SimpleStrategy(t *testing.T) {
// now the token ring is configured
query.RoutingKey([]byte("20"))
iter = policy.Pick(query)
iterCheck(t, iter, "0")
iterCheck(t, iter, "1")
iterCheck(t, iter, "2")
}

// Tests of the host pool host selection policy implementation
Expand Down Expand Up @@ -608,7 +608,7 @@ func TestHostPolicy_TokenAware_NetworkStrategy(t *testing.T) {
}, policyInternal.getMetadataReadOnly().replicas)

// now the token ring is configured
query.RoutingKey([]byte("23"))
query.RoutingKey([]byte("18"))
iter = policy.Pick(query)
// first should be hosts with matching token from the local DC
iterCheck(t, iter, "4")
Expand Down
10 changes: 0 additions & 10 deletions topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,9 @@ func (h tokenRingReplicas) replicasFor(t token) *hostTokens {
return !h[i].token.Less(t)
})

// TODO: simplify this
if p < len(h) && h[p].token == t {
return &h[p]
}

p--

if p >= len(h) {
// rollover
p = 0
} else if p < 0 {
// rollunder
p = len(h) - 1
}

return &h[p]
Expand Down

0 comments on commit 9b18429

Please sign in to comment.