Se connecter à Spanner à l'aide de l'adaptateur Cassandra

Cette page décrit l'adaptateur Cassandra et explique comment l'utiliser et connecter Spanner à partir de celui-ci.

L'adaptateur Cassandra est conçu pour s'exécuter sur la même machine que votre application. L'adaptateur expose un point de terminaison sur localhost qui est compatible avec le protocole filaire du langage de requête Cassandra (CQL). Il traduit le protocole de communication CQL en gRPC, le protocole de communication Spanner. Avec ce proxy exécuté localement, un client Cassandra peut se connecter à une base de données Spanner.

Vous pouvez démarrer l'adaptateur Cassandra de différentes manières :

  • En cours de traitement avec votre application Go
  • En cours de traitement avec votre application Java
  • En tant que processus autonome
  • Dans un conteneur Docker

Avant de commencer

Avant de démarrer l'adaptateur Cassandra, assurez-vous de vous être authentifié avec un compte utilisateur ou un compte de service sur la machine sur laquelle l'adaptateur Cassandra sera exécuté. Si vous utilisez un compte de service, vous devez connaître l'emplacement du fichier de clé JSON (fichier d'identifiants). Vous définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS pour spécifier le chemin d'accès aux identifiants.

Pour en savoir plus, consultez les pages suivantes :

Connecter l'adaptateur Cassandra à votre application

L'adaptateur Cassandra nécessite les informations suivantes :

  • Nom du projet
  • Nom de l'instance Spanner
  • Base de données à laquelle se connecter

Si vous utilisez Docker, vous avez besoin du chemin d'accès à un fichier d'identifiants au format JSON (fichier de clé).

Java in-process

  1. Si vous utilisez un compte de service pour l'authentification, assurez-vous que la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS est définie sur le chemin d'accès au fichier d'identifiants.

  2. Pour les applications Java, vous pouvez associer l'adaptateur Cassandra directement à l'application en ajoutant google-cloud-spanner-cassandra comme dépendance à votre projet.

Pour Maven, ajoutez la nouvelle dépendance suivante sous la section <dependencies> :

<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-spanner-cassandra</artifactId>
    <version>0.4.0</version>
</dependency>

Pour Gradle, ajoutez l'extrait suivant :

dependencies {
    implementation 'com.google.cloud:google-cloud-spanner-cassandra:0.4.0'
}

  1. Modifiez le code de création de votre CqlSession. Au lieu d'utiliser CqlSessionBuilder, utilisez SpannerCqlSessionBuilder et fournissez l'URI de la base de données Spanner :
    
    import com.datastax.oss.driver.api.core.CqlSession;
    import com.datastax.oss.driver.api.core.config.DefaultDriverOption;
    import com.datastax.oss.driver.api.core.config.DriverConfigLoader;
    import com.datastax.oss.driver.api.core.cql.ResultSet;
    import com.datastax.oss.driver.api.core.cql.Row;
    import com.google.cloud.spanner.adapter.SpannerCqlSession;
    import java.net.InetSocketAddress;
    import java.time.Duration;
    import java.util.Random;
    
    // This sample assumes your spanner database <my_db> contains a table <users>
    // with the following schema:
    
    // CREATE TABLE users (
    //  id        INT64          OPTIONS (cassandra_type = 'int'),
    //  active    BOOL           OPTIONS (cassandra_type = 'boolean'),
    //  username  STRING(MAX)    OPTIONS (cassandra_type = 'text'),
    // ) PRIMARY KEY (id);
    
    class QuickStartSample {
    
      public static void main(String[] args) {
    
        // TODO(developer): Replace these variables before running the sample.
        final String projectId = "my-gcp-project";
        final String instanceId = "my-spanner-instance";
        final String databaseId = "my_db";
    
        final String databaseUri =
            String.format("projects/%s/instances/%s/databases/%s", projectId, instanceId, databaseId);
    
        try (CqlSession session =
            SpannerCqlSession.builder() // `SpannerCqlSession` instead of `CqlSession`
                .setDatabaseUri(databaseUri) // Set spanner database URI.
                .addContactPoint(new InetSocketAddress("localhost", 9042))
                .withLocalDatacenter("datacenter1")
                .withKeyspace(databaseId) // Keyspace name should be the same as spanner database name
                .withConfigLoader(
                    DriverConfigLoader.programmaticBuilder()
                        .withString(DefaultDriverOption.PROTOCOL_VERSION, "V4")
                        .withDuration(
                            DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofSeconds(5))
                        .build())
                .build()) {
    
          final int randomUserId = new Random().nextInt(Integer.MAX_VALUE);
    
          System.out.printf("Inserting user with ID: %d%n", randomUserId);
    
          // INSERT data
          session.execute(
              "INSERT INTO users (id, active, username) VALUES (?, ?, ?)",
              randomUserId,
              true,
              "John Doe");
    
          System.out.printf("Successfully inserted user: %d%n", randomUserId);
          System.out.printf("Querying user: %d%n", randomUserId);
    
          // SELECT data
          ResultSet rs =
              session.execute("SELECT id, active, username FROM users WHERE id = ?", randomUserId);
    
          // Get the first row from the result set
          Row row = rs.one();
    
          System.out.printf(
              "%d %b %s%n", row.getInt("id"), row.getBoolean("active"), row.getString("username"));
    
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    

Passer à l'état "En cours"

Pour les applications Go, vous devez modifier une ligne du fichier d'initialisation du cluster afin d'intégrer le client Go Spanner Cassandra. Vous pouvez ensuite associer l'adaptateur Cassandra directement à l'application.

  1. Importez le package spanner de l'adaptateur à partir du client Go Spanner/Cassandra dans votre application Go.
import spanner "github.com/googleapis/go-spanner-cassandra/cassandra/gocql"
  1. Modifiez le code de création de votre cluster pour utiliser spanner.NewCluster au lieu de gocql.NewCluster, et fournissez l'URI de la base de données Spanner :
    import (
    	"fmt"
    	"io"
    	"math"
    	"math/rand/v2"
    	"time"
    
    	spanner "github.com/googleapis/go-spanner-cassandra/cassandra/gocql"
    )
    
    // This sample assumes your spanner database <your_db> contains a table <users>
    // with the following schema:
    //
    // CREATE TABLE users (
    //	id   	 	INT64          OPTIONS (cassandra_type = 'int'),
    //	active    	BOOL           OPTIONS (cassandra_type = 'boolean'),
    //	username  	STRING(MAX)    OPTIONS (cassandra_type = 'text'),
    // ) PRIMARY KEY (id);
    
    func quickStart(databaseURI string, w io.Writer) error {
    	opts := &spanner.Options{
    		DatabaseUri: databaseURI,
    	}
    	cluster := spanner.NewCluster(opts)
    	if cluster == nil {
    		return fmt.Errorf("failed to create cluster")
    	}
    	defer spanner.CloseCluster(cluster)
    
    	// You can still configure your cluster as usual after connecting to your
    	// spanner database
    	cluster.Timeout = 5 * time.Second
    	cluster.Keyspace = "your_db_name"
    
    	session, err := cluster.CreateSession()
    
    	if err != nil {
    		return err
    	}
    
    	randomUserId := rand.IntN(math.MaxInt32)
    	if err = session.Query("INSERT INTO users (id, active, username) VALUES (?, ?, ?)",
    			       randomUserId, true, "John Doe").
    		Exec(); err != nil {
    		return err
    	}
    
    	var id int
    	var active bool
    	var username string
    	if err = session.Query("SELECT id, active, username FROM users WHERE id = ?",
    			       randomUserId).
    		Scan(&id, &active, &username); err != nil {
    		return err
    	}
    	fmt.Fprintf(w, "%d %v %s\n", id, active, username)
    	return nil
    }

Vous pouvez configurer votre cluster comme d'habitude après vous être connecté à votre base de données Spanner.

Autonome

  1. Clonez le dépôt :
git clone https://github.com/googleapis/go-spanner-cassandra.git
cd go-spanner-cassandra
  1. Exécutez cassandra_launcher.go avec l'option -db requise :
go run cassandra_launcher.go \
-db "projects/my_project/instances/my_instance/databases/my_database"
  1. Remplacez -db par l'URI de votre base de données Spanner.

Docker

Démarrez l'adaptateur Cassandra à l'aide de la commande suivante.

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
docker run -d -p 9042:9042 \
-e GOOGLE_APPLICATION_CREDENTIALS \
-v ${GOOGLE_APPLICATION_CREDENTIALS}:${GOOGLE_APPLICATION_CREDENTIALS}:ro \
gcr.io/cloud-spanner-adapter/cassandra-adapter \
-db DATABASE_URI

La liste suivante contient les options de démarrage les plus fréquemment utilisées pour l'adaptateur Spanner Cassandra :

  • -db <DatabaseUri>

URI de la base de données Spanner (obligatoire). Indique la base de données Spanner à laquelle le client se connecte. Par exemple, projects/YOUR_PROJECT/instances/YOUR_INSTANCE/databases/YOUR_DATABASE.

  • -tcp <TCPEndpoint>

Adresse du listener du proxy client. Cela définit le point de terminaison TCP où le client écoute les connexions client Cassandra entrantes. Par défaut : localhost:9042

  • -grpc-channels <NumGrpcChannels>

Nombre de canaux gRPC à utiliser lors de la connexion à Spanner. Valeur par défaut : 4

Par exemple, la commande suivante démarre l'adaptateur Cassandra sur le port 9042 à l'aide des identifiants de l'application et connecte l'adaptateur à la base de données projects/my_project/instances/my_instance/databases/my_database :

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
docker run -d -p 9042:9042 \
-e GOOGLE_APPLICATION_CREDENTIALS \
-v ${GOOGLE_APPLICATION_CREDENTIALS}:${GOOGLE_APPLICATION_CREDENTIALS}:ro \
gcr.io/cloud-spanner-adapter/cassandra-adapter \
-db projects/my_project/instances/my_instance/databases/my_database

Recommandations

Les recommandations suivantes vous aident à améliorer votre expérience avec l'adaptateur Cassandra. Ces recommandations sont axées sur Java, en particulier sur le pilote client Cassandra pour Java version 4.

Augmenter le délai avant expiration de la requête

Un délai d'expiration de la requête de cinq secondes ou plus offre une meilleure expérience avec l'adaptateur Cassandra que la valeur par défaut de deux secondes.

# Sample application.conf: increases request timeout to five seconds
datastax-java-driver {
  basic {
    request {
      timeout = 5 seconds
    }
  }
}

Ajuster le regroupement de connexions

Les configurations par défaut pour le nombre maximal de connexions et le nombre maximal de requêtes simultanées par connexion ou hôte sont appropriées pour les environnements de développement, de test et de production ou de préproduction à faible volume. Toutefois, nous vous recommandons d'augmenter ces valeurs, car l'adaptateur Cassandra se fait passer pour un nœud unique, contrairement à un pool de nœuds dans un cluster Cassandra.

L'augmentation de ces valeurs permet d'établir davantage de connexions simultanées entre le client et l'interface Cassandra. Cela peut éviter l'épuisement du pool de connexions en cas de forte charge.

# Sample application.conf: increases maximum number of requests that can be
# executed concurrently on a connection
advanced.connection {
  max-requests-per-connection = 32000
  pool {
    local.size = 10
  }
}

Régler les canaux gRPC

Les canaux gRPC sont utilisés par le client Spanner pour la communication. Un canal gRPC équivaut à peu près à une connexion TCP. Un canal gRPC peut gérer jusqu'à 100 requêtes simultanées. Cela signifie qu'une application aura besoin d'au moins autant de canaux gRPC que le nombre de requêtes simultanées qu'elle exécutera, divisé par 100.

Désactiver le routage basé sur les jetons

Les pilotes qui utilisent l'équilibrage de charge compatible avec les jetons peuvent afficher un avertissement ou ne pas fonctionner lorsqu'ils utilisent l'adaptateur Cassandra. Étant donné que l'adaptateur Cassandra se fait passer pour un nœud unique, il ne fonctionne pas toujours bien avec les pilotes compatibles avec les jetons qui s'attendent à ce qu'il y ait au moins un nombre de nœuds correspondant au facteur de réplication dans le cluster. Certains pilotes peuvent imprimer un avertissement (qui peut être ignoré) et revenir à une stratégie d'équilibrage de type "round-robin", tandis que d'autres pilotes peuvent échouer avec une erreur. Pour les pilotes qui échouent avec une erreur, vous devez désactiver la prise en compte des jetons ou configurer la stratégie d'équilibrage de charge round robin.

# Sample application.conf: disables token-aware routing
metadata {
  token-map {
    enabled = false
  }
}

Épingler la version du protocole sur V4

L'adaptateur Cassandra est compatible avec n'importe quel pilote client Apache Cassandra Open Source conforme au protocole filaire CQL Binary v4. Assurez-vous d'épingler PROTOCOL_VERSION à V4, sinon des erreurs de connexion peuvent s'afficher.

# Sample application.conf: overrides protocol version to V4
datastax-java-driver {
  advanced.protocol.version = V4
}

Étapes suivantes