Description
See the following snippet from TokenAwarePolicy.java
@Override
protected Host computeNext() {
while (replicasIterator.hasNext()) {
Host host = replicasIterator.next();
if (host.isUp() && childPolicy.distance(host) == HostDistance.LOCAL) return host;
}
...
This is how we calculate the first hosts in query plan in case of ReplicaOrdering.RANDOM
. We prioritise replicas (which have been random shuffled beforehand) and select first those that according to child policy are local replicas. The problem is with distance
implementation of RackAwareRoundRobinPolicy
@Override
public HostDistance distance(Host host) {
String dc = dc(host);
if (dc == UNSET || dc.equals(localDc)) return HostDistance.LOCAL;
CopyOnWriteArrayList<Host> dcHosts = perDcLiveHosts.get(dc);
if (dcHosts == null || usedHostsPerRemoteDc == 0) return HostDistance.IGNORED;
// We need to clone, otherwise our subList call is not thread safe
dcHosts = cloneList(dcHosts);
return dcHosts.subList(0, Math.min(dcHosts.size(), usedHostsPerRemoteDc)).contains(host)
? HostDistance.REMOTE
: HostDistance.IGNORED;
}
On its own this policy prioritizes first local rack, then remote racks but in local DC then remote DCs. However, HostDistance
right now only differentiates between LOCAL
, REMOTE
and IGNORED
. If this policy is used with random ordering token aware policy then if remote rack but local dc replica comes first in the list of replicas, then it will be considered LOCAL
according to this code snippet, invalidating the property of local rack going first. It's effectively DCAware and not RackAware in that configuration.