【问题标题】:core number of connections must be positive error核心连接数必须为正错误
【发布时间】:2016-11-23 21:55:27
【问题描述】:

我正在使用 datastax java driver 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 节点连接。

【问题讨论】:

    标签: java cassandra datastax-java-driver


    【解决方案1】:

    PoolingOptions 可以使用不同版本的协议(V2、V3、V4),每个版本都有不同的默认值。为了确定哪种协议最好,驱动程序必须首先与 Cassandra 通信,然后设置默认值,直到那时驱动程序使用-1。当您查看 PoolingOptions 时,它甚至包含在默认值之上的 cmets 中(其中 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

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

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

    【讨论】:

    • 那么我应该在我的客户端代码中做些什么来解决这个问题?我应该在哪里使用LOCAL_ONE?我已经在使用 HOSTDISTANCE LOCAL,是不是一样的东西?
    • 问题是我们在开发中的 cassandra 版本可能与生产版本不同。我的意思是它们可能不是相同的确切版本,所以在这种情况下我们应该怎么做?
    • 好的,我发现我们使用的是2.0.10 Cassandra 版本。
    • 您正在使用 DCAwareLoadBalancingPolicy,如果您使用 LOCAL_ 版本的查询编写和读取查询,它将更喜欢本地 DC。我会放弃池化选项的一部分,因为它不是必需的(让 Cassandra 根据协议版本设置默认值)并在读/写时使用 LOCAL_ 。如果您想阻止与远程 DC 的通信,请尝试仅使用 RoundRobinPolicy 而不是 DCAware 或将其包装在 WhiteLabel 策略中,该策略将仅过滤掉您想要的主机。
    猜你喜欢
    • 2018-07-08
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 2021-10-25
    • 2022-06-29
    • 1970-01-01
    相关资源
    最近更新 更多