【问题标题】:connect to local cassandra nodes using datastax java driver?使用datastax java驱动程序连接到本地cassandra节点?
【发布时间】:2016-11-24 05:23:49
【问题描述】:

我正在使用 datastax java driver 3.1.0 连接到 cassandra 集群,我的 cassandra 集群版本是 2.0.10。

下面是我用来连接到 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);

    // is this right setting?
    PoolingOptions poolingOptions = new PoolingOptions();
    poolingOptions.setConnectionsPerHost(HostDistance.LOCAL, 4, 10).setConnectionsPerHost(
        HostDistance.REMOTE, 2, 4);

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

    try {
      session = cluster.connect("testkeyspace");
      StringBuilder sb = new StringBuilder();
      Set<Host> allHosts = cluster.getMetadata().getAllHosts();
      for (Host host : allHosts) {
        sb.append("[");
        sb.append(host.getDatacenter());
        sb.append(host.getRack());
        sb.append(host.getAddress());
        sb.append("]");
      }
      LOGGER.logInfo("connected: " + sb.toString());
    } catch (NoHostAvailableException ex) {
      LOGGER.logError("error= ", ExceptionUtils.getStackTrace(ex));
    } catch (Exception ex) {
      LOGGER.logError("error= " + ExceptionUtils.getStackTrace(ex));
    }
  }

  public void shutdown() {
    LOGGER.logInfo("Shutting down the whole cassandra cluster");
    if (null != session) {
      session.close();
    }
    if (null != cluster) {
      cluster.close();
    }
  }

  public Session getSession() {
    if (session == null) {
      throw new IllegalStateException("No connection initialized");
    }
    return session;
  }

  public Cluster getCluster() {
    return cluster;
  }
}

我需要使用哪些设置来首先连接到本地 cassandra 节点,如果它们关闭,则只与远程节点通信。我在上面的代码中使用的池配置选项也在这里?

【问题讨论】:

    标签: java cassandra datastax-java-driver


    【解决方案1】:

    默认情况下,datastax 驱动程序只会连接到本地 DC 中的节点。如果您不使用withLocalDc,它将尝试将本地数据中心与其能够连接到的联络点的 DC 区分开来。

    如果您希望驱动程序故障转移到远程数据中心的主机,您应该使用withUsedHostsPerRemoteDc,即:

    cluster.builder()        
      .withLoadBalancingPolicy(DCAwareRoundRobinPolicy.builder()
        .withLocalDc("DC1")
        .withUsedHostsPerRemoteDc(3).build())
    

    使用此配置,驱动程序将与每个远程 DC 中的 3 台主机建立连接,并且仅当本地数据中心中的所有主机都关闭时才向它们发送查询。

    还有其他用于故障转移到远程数据中心的策略。例如,您可以在与 C* 数据中心相同的每个物理数据中心运行应用程序客户端,然后当物理数据中心出现故障时,您可以在更高级别(如负载均衡器)进行故障转移。

    我在上面的代码中使用的池配置选项也在这里?

    我认为你所拥有的一切都很好。默认值也很好。

    【讨论】:

    • 假设我们在每个数据中心没有 3 个节点,那么如果我们在那里指定 3 会发生什么?还是必须是数据中心的机器数量?
    • 3 是一个天花板,所以如果远程 DC 中只有 2 个节点,它将连接到 2。
    • 我还有一个与 datastax java 驱动程序here 相关的问题。想看看你能不能帮帮我?
    猜你喜欢
    • 2018-04-16
    • 2013-12-23
    • 2014-11-07
    • 2021-02-09
    • 2016-02-18
    • 2015-08-16
    • 1970-01-01
    • 2016-09-28
    • 2013-07-14
    相关资源
    最近更新 更多