如何在Cassandra3中强制仅远程读取?

时间:2018-11-02 15:48:40

标签: java database cassandra benchmarking cassandra-3.0

我们正在尝试修改Cassandra代码以仅执行远程读取(从不本地读取),以进行推测性重试和请求复制等待时间减少技术的性能测试。

到目前为止,我们已经修改了 src / java / org / apache / cassandra / service / AbstractReadExecutor.java 做这样的事情:

public abstract class AbstractReadExecutor {
  protected int getNonLocalEndpointIndex (Iterable<InetAddress> endpoints) {
    int endpoint_index = 0;

    // iterate thru endpoints and pick non-local one
    boolean found = false;
    for (InetAddress e : endpoints) {
     if (! StorageProxy.canDoLocalRequest(e) ) {
        found = true;
        break;
     }
     endpoint_index++;
    }

    if (!found) {
        endpoint_index = 0;
    }
    return endpoint_index;
   }
}


public static class NeverSpeculatingReadExecutor extends AbstractReadExecutor {
   public void executeAsync() {
         int endpoint_index = getNonLocalEndpointIndex(targetReplicas);
         makeDataRequests(targetReplicas.subList(endpoint_index, endpoint_index+1));

         if (targetReplicas.size() > 1)
             makeDigestRequests(targetReplicas.subList(1, targetReplicas.size()));
         }
    }
}

但是,它不起作用,因为targetReplicas几乎总是1个端点(本地端点),以使用小型工作负载,5个cassandra节点和3的复制因子。

2 个答案:

答案 0 :(得分:0)

如果这仅是为了进行测试,则可以将1个节点设置为错误的DC,并使用LOCAL查询该节点不拥有的东西(驱动程序上的白名单负载平衡策略,以确保仅将请求发送给它)。只需要做一下,仅测试节点不拥有其副本的情况即可。

还是您有兴趣做一些事情,例如在读取修复中测试代理突变?

答案 1 :(得分:0)

我只能通过添加一个函数“ getRemoteReplicas()”来进行远程读取,该函数在创建ReadExecutor对象之前/之时过滤掉本地节点。 ConstanceLevel.filterForQuery()通常通常只返回1个节点(非本地节点)。

public static AbstractReadExecutor getReadExecutor(...) {
    ...
    List<InetAddress> remoteReplicas = getRemoteReplicas( allReplicas );
    List<InetAddress> targetReplicas = consistencyLevel.filterForQuery(keyspace, remoteReplicas, repairDecision);
    ...
}

private static List<InetAddress> getRemoteReplicas(List<InetAddress> replicas) {
    logger.debug("ALL REPLICAS: " + replicas.toString());
    List<InetAddress> remote_replicas = new ArrayList<>();

    // iterate thru replicas and pick non-local one
    boolean found = false;
    for (InetAddress r : replicas) {
        if (! StorageProxy.canDoLocalRequest(r) ) {
            remote_replicas.add(r);
            found = true;
        }
    }
    if (!found) {
      return replicas;
    }
    logger.debug("REMOTE REPLICAS: " + remote_replicas.toString());
    return remote_replicas;
}

在src / java / org / apache / cassandra / service / AbstractReadExecutor.java