java-driver icon indicating copy to clipboard operation
java-driver copied to clipboard

[3.x] `RackAwareRoundRobinPolicy` seems incompatible with `ReplicaOrdering.RANDOM` in `TokenAwarePolicy`

Open Bouncheck opened this issue 1 year ago • 6 comments

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.

Bouncheck avatar Nov 19 '24 09:11 Bouncheck