核心连接数必须为正误差

时间:2016-11-23 06:43:14

标签: java cassandra datastax-java-driver

我使用datastax java驱动程序3.1.0连接到cassandra。我想连接到本地cassandra节点,而不是连接远程cassandra节点。

public class CassUtil {
  private static final Logger LOGGER = Logger.getInstance(CassUtil.class);
  private Session session;
  private Cluster cluster;

  private static class Holder {
    private static final CassUtil INSTANCE = new CassUtil();
  }

  public static CassUtil getInstance() {
    return Holder.INSTANCE;
  }

  private CassUtil() {
    List<String> servers = TestUtils.HOSTNAMES;
    String username =
        TestUtils.loadCredentialFile().getProperty(TestUtils.USERNAME);
    String password =
        TestUtils.loadCredentialFile().getProperty(TestUtils.PASSWORD);

    // this code throws exception
    PoolingOptions opts = new PoolingOptions();
    opts.setCoreConnectionsPerHost(HostDistance.LOCAL,
        opts.getCoreConnectionsPerHost(HostDistance.LOCAL));

    Builder builder = Cluster.builder();
    cluster =
        builder
            .addContactPoints(servers.toArray(new String[servers.size()]))
            .withRetryPolicy(DowngradingConsistencyRetryPolicy.INSTANCE)
            .withPoolingOptions(opts)
            .withReconnectionPolicy(new ConstantReconnectionPolicy(100L))
            .withLoadBalancingPolicy(
                DCAwareRoundRobinPolicy
                    .builder()
                    .withLocalDc(
                        !TestUtils.isProduction() ? "ABC2" : TestUtils.getCurrentLocation()
                            .get().name().toLowerCase()).build())
            .withCredentials(username, password).build();

    try {
      session = cluster.connect("testkeyspace");
    } catch (NoHostAvailableException ex) {
      LOGGER.logError("error= ", ExceptionUtils.getStackTrace(ex));
    } catch (Exception ex) {
      LOGGER.logError("error= " + ExceptionUtils.getStackTrace(ex));
    }
  }
}

每当我在代码上运行时,它都会给我一个例外:

Caused by: java.lang.IllegalArgumentException: core number of connections must be positive
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
    at com.datastax.driver.core.PoolingOptions.setCoreConnectionsPerHost(PoolingOptions.java:199)

另外,我想确保我的客户端始终与本地cassandra节点连接,而不是与任何远程cassandra节点连接。

1 个答案:

答案 0 :(得分:2)

PoolingOptions可以使用不同版本的协议(V2,V3,V4),每个版本都有不同的默认值。为了确定哪个协议最佳,驱动程序必须首先与Cassandra通信,然后设置默认值,然后驱动程序使用-1。当您查看PoolingOptions时,这甚至包含在默认值以上的评论中(其中UNSET常量为-1):

// The defaults for these fields depend on the protocol version, which is only known after control connection initialization.
// Yet if the user set them before initialization, we want to keep their values. So we use -1 to mean "uninitialized".
private final int[] coreConnections = new int[]{UNSET, UNSET, 0};

当你看到getter时,你正在使用它从同一个数组中读取:

public int getCoreConnectionsPerHost(HostDistance distance) {
    return coreConnections[distance.ordinal()];
}

在群集初始化时,这将有效地返回-1

您可以显式设置协议版本,该版本将使用正确的默认值填充数组(在此link上检查DataStax表中的Cassandra / DSE版本和协议版本)或者您可以将核心连接设置为某个所需的正数而不是使用getter。

关于本地问题,您可以使用LOCAL_ONE/LOCAL_ANY/LOCAL_QUORUM来选择本地节点而不是远程(在不同的DC中)。