Address Translation Maps

About improving resilience and reliability with ScyllaDB address translation maps

To get the best out of a Scylla database client, it is best to connect to all the nodes of the database. This is why the ContactPoints parameter for connections is an array. A Compose Scylla address translation map provides the information needed by various drivers to navigate between the internal IP addresses and external DNS names of a Scylla database.

Currently, drivers for Node.js, Java, and Groovy work with address translation maps. Other drivers might require changes to work correctly with Compose's network configuration, such as the Python driver which assumes all connections will use the same port.

Using the Address Translation Map

You can find the Address Translation Map in the Connection info section of your Compose console Overview for Scylla:

1789

An example Address Translation Map.

The address translation map is designed to act as a snippet that you can add to your application or a configuration file. It is made up of an internal private network address and port and an external network address and port. Applications connect to the external network addresses. Here's an example:

{
    "10.0.24.69:9042": "sl-eu-lon-2-portal.3.dblayer.com:15227",
    "10.0.24.71:9042": "sl-eu-lon-2-portal.2.dblayer.com:15229",
    "10.0.24.70:9042": "sl-eu-lon-2-portal.1.dblayer.com:15228"
}

To use this for any driver that supports address translation, an application needs to create an address translator, load the translator with this information and tell the driver to use the translator when connecting to a cluster.

Address translation with NodeJS

To add address map translation support to an application that already uses the cassandra-driver for NodeJS, include the composeaddresstranslator npm package in your NodeJS application. The git repository for this package can be found in the Compose-example repository.

$ npm install composeaddresstranslator --save

In the application code itself, add a requirement for the new package.

var compose = require('composeaddresstranslator');
...

Elsewhere in the code, copy and paste in the address translation map, then create an instance of the composeaddresstranslator and pass the map to the instance.

addresses= {
    "10.0.24.69:9042": "sl-eu-lon-2-portal.3.dblayer.com:15227",
    "10.0.24.71:9042": "sl-eu-lon-2-portal.2.dblayer.com:15229",
    "10.0.24.70:9042": "sl-eu-lon-2-portal.1.dblayer.com:15228"
}

translator=new compose.ComposeAddressTranslator();
 
translator.setMap(addresses);

When it comes to creating the Cassandra client, for the ContactPoints parameter, replace the value with translator.getContactPoints(), which returns an array of the external addresses and ports and removes any need to duplicate connection information in the code. Setting policies. addressResolution to the translator instance ensures it is used by the application.

client = new cassandra.Client({
    contactPoints: translator.getContactPoints(),
    policies: {
        addressResolution: translator
    },
    authProvider: authProvider
});

When a client connects, it will know immediately about all nodes and connection portals available. You do not need to make any other changes.

Address translation with Java

The java-composeaddresstranslator example includes a ComposeAddressTranslator class. Use com.compose.scyllacompose.ComposeAddressTranslator as part of your application's code base and import it into your application.

Java does not have native JSON handling, so the ComposeAddressTranslator parses a JSON string representation of either an object or an array as the source for the map. Java also lacks multiline string support, so embedding the address translation map in code is in-elegant:

String mapstring = "{\n"
      + "   \"10.0.24.69:9042\": \"sl-eu-lon-2-portal.3.dblayer.com:15227\",\n"
      + "   \"10.0.24.71:9042\": \"sl-eu-lon-2-portal.2.dblayer.com:15229\",\n"
      + "   \"10.0.24.70:9042\": \"sl-eu-lon-2-portal.1.dblayer.com:15228\"\n"
      + "}";

ComposeAddressTranslator translator = new ComposeAddressTranslator();
translator.setMap(mapstring);

In production, your application should read the address translation map from a configuration file.

With the translator instance created, the Java API uses Cluster.builder() to create a new cluster for connections. Like the Node.js translator, the Java translator also provides a list of hosts, which can be used with .addContactPointsWithPorts(). To ensure the address translator is being used the .withAddressTranslator() function should also be used to pass the translator instance to the cluster. The code for this is as follows:

cluster = Cluster.builder()
                    .addContactPointsWithPorts(translator.getContactPoints())
                    .withAddressTranslator(translator)
                    .withCredentials("scylla", "PASSWORD")
                    .build();

    Session session = cluster.connect();

The application can then continue to make calls on the cluster and session objects.

Address translation with Groovy

As a JVM-based and Java-compatible language, Groovy can use the Java ComposeAddressTranslator class detailed in the previous section. A full example is included in the Groovy connection repository.


Still Need Help?

If this article didn't solve things, summon a human and get some help!