Apache Cassandra DefaultRetryPolicy不支持网络断开连接?

时间:2017-08-01 11:55:25

标签: cassandra datastax-java-driver

我正在使用datastax cassandra驱动核心3.1.0,并开始学习cassandra我已经设置了一个3节点集群(我的笔记本电脑中运行了3个VM)。

群集连接以这种方式完成(传递联系点列表):

public static Cluster createCassandraRockSolidCluster(String... contactPoints) {

    // Connect to the cluster
    Cluster cluster = Cluster.builder().addContactPoints(contactPoints).withRetryPolicy(DefaultRetryPolicy.INSTANCE)
            .withLoadBalancingPolicy(new TokenAwarePolicy(DCAwareRoundRobinPolicy.builder().build())).build();
    return cluster;
}

我已经创建了一个测试,它定期对集群执行相同的查询,并设置了ConsistencyLevel.ONE。

我的期望是,如果一个或甚至两个节点发生故障,查询仍然可以获得结果(由于ConsistencyLevel.ONE和DefaultRetryPolicy)。

发生的事情是:

  1. 如果我关闭一个节点甚至其中两个节点,通过停止cassandra服务,客户端的查询就像我期望的那样工作:它检索结果没有任何问题。

  2. 但是,如果我真的"断开电缆"从一个服务器的网络适配器使其无法访问,然后引发一个超时异常,一个查询丢失(下一个查询能够检索数据)。

  3. 这不是我所期待的,我想知道这是我的错误还是java客户端库中的错误。

    另一方面,如果我抓住了Exception,并且"重新执行"超时查询,它可以工作,但我希望这个重试将由DefaultRetryPolicy管理。

    因此,为了给我的客户提供额外的健壮性,我创建了这个方法:

        protected static ResultSet executeRockSolid(Session session, BoundStatement boundStatement) {
        ResultSet results = null;
        try {
            results = session.execute(boundStatement);
        } catch (OperationTimedOutException e) {
            System.err.format("Retrying. Caused by: %s", e.toString());
            results = session.execute(boundStatement);
        } catch (TransportException e) {
            System.err.format("Retrying. Caused by: %s", e.toString());
            results = session.execute(boundStatement);
        } catch (ReadTimeoutException e) {
            System.err.format("Retrying. Caused by: %s", e.toString());
            results = session.execute(boundStatement);
        } catch (Exception e) {
            System.err.println(e);
        }
    
        return results;
    }
    

    但是,我真的不喜欢将自己的代码用于我认为应由客户提供的内容。

    所以,问题是:

    我观察的行为是正常行为还是错误?

    如果是正常的,那么最好的选择是让客户端支持"服务器与网络的连接断开"透明?

    如果最佳选择是创建自定义重试策略,那么参数/实现是什么?

0 个答案:

没有答案