我使用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节点连接。
答案 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中)。