Bringing together the Apache Cassandra experts from the community and DataStax.

Want to learn? Have a question? Want to share your expertise? You are in the right place!

Not sure where to begin? Getting Started

 

question

reginahart avatar image
reginahart asked reginahart commented

How do I deal with the error "the local DC must be explicitly set" in Java driver 4.x?

Datastax 4+CqlSession ->error"the local DC must be explicitly set" when creating session specifying contactpoints -multiple datacenters?

Our Java app with cassandra code is currently connecting (driver 2+) using clusterFactory with list of servers. The cassandra servers are remote. In our live environment there are 2 datacenters - 50% of the servers are configured in each DC. Programmatically and in configuration there is only an option for .withLocalDatacenter(). How do I manage this?

java driver
1 comment
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Removing question

0 Likes 0 ·
Erick Ramirez avatar image
Erick Ramirez answered reginahart commented

If you're using the default load balancing policy in Java driver 4.x, you need to tell the driver which DC is local to it. Otherwise, the driver doesn't know which nodes are in the same DC as the app servers, and which nodes are in a different DC.

In your case, you have added nodes from both DCs as contact points so the driver doesn't know which nodes are in the local DC. Here's an example where node 10.1.2.3 belongs in DC1, 10.4.5.6 belongs in DC2, the app is in the 10.1.x.x subnet so I'm telling the driver DC1 is the local DC:

CqlSession session = CqlSession.builder()
    .addContactPoint(new InetSocketAddress("10.1.2.3", 9042))
    .addContactPoint(new InetSocketAddress("10.4.5.6", 9042))
    .withLocalDatacenter("DC1")
    .build();

As a side note, I suggest using the configuration file to specify the options so you don't need to recompile your app every time you make configuration changes.

Here's the equivalent application.conf entry:

datastax-java-driver {
  basic {
    contact-points = [ "10.1.2.3.:9042", "10.4.5.6:9042" ]
    load-balancing-policy.local-datacenter = DC1
  }
}

For details, see the Core driver page of the Java driver doc. Cheers!

4 comments Share
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

But can I do this?

datastax-java-driver {
  basic {
    contact-points = [ "10.1.2.3.:9042", "10.4.5.6:9042" ]
    load-balancing-policy.local-datacenter = DC1
  }
  basic {
    contact-points = [ "10.1.152.3.:9042", "10.4.152.6:9042" ]
    load-balancing-policy.local-datacenter = DC2
  }
}

Programatically, I have tried this (dosen't work)

error is: Multiple entries with same key: default=dc2 and default=dc1

CqlSession session = CqlSession.builder()
        .withAuthCredentials(config.getUser(), config.getPassword())
        .addContactEndPoints(endpoints1)
        .withLocalDatacenter(config.getLocalDatacenter1())
        .addContactEndPoints(endpoints2)
        .withLocalDatacenter(config.getLocalDatacenter2())
        .build();
0 Likes 0 ·

What you're doing won't work because you can't tell the driver there are 2 DCs which are local. By definition, only 1 DC can be local. Cheers!

0 Likes 0 ·

How to connect to multiple remote nodes accross multiple datacenters please? It was fine with ClusterFactory (versions 2 & 3)

0 Likes 0 ·

If you're using the default load balancing policy (DefaultLoadBalancingPolicy), you can't specify remote nodes -- this is a breaking change in Java driver 4.x compared to earlier versions of the driver.

If you want your app to be able to connect to remote nodes, you can only do it with Java driver 4.10+ and you need to use an advanced load balancing policy. For details, see the Load balancing section of the Java driver doc. Cheers!

0 Likes 0 ·
smadhavan avatar image
smadhavan answered

@reginahart, if you're trying to perform cross-datacenter failover for scenarios where your default designated datacenter goes for a toss, beginning with 4.10.0, you could achieve that by following this documentation. In case your application is wanting to work with a transactional DC and analytical DC for example, you could leverage Execution Profiles to achieve sending requests based on your needs to different datacenters. Hope this helps!

Share
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.