Connettiti a Spanner utilizzando l'adattatore Cassandra

Questa pagina descrive l'adattatore Cassandra e spiega come utilizzarlo e connettere Spanner.

L'adattatore Cassandra è progettato per essere eseguito sulla stessa macchina dell'applicazione. L'adattatore espone un endpoint su localhost che supporta il protocollo Cassandra Query Language (CQL). Traduce il protocollo di rete CQL in gRPC, il protocollo di rete Spanner. Con questo proxy in esecuzione in locale, un client Cassandra può connettersi a un database Spanner.

Puoi avviare l'adattatore Cassandra nei seguenti modi:

  • In-process con la tua applicazione Go
  • In-process con la tua applicazione Java
  • Come processo autonomo
  • In un container Docker

Prima di iniziare

Prima di avviare Cassandra Adapter, assicurati di aver eseguito l'autenticazione con un account utente o di servizio sulla macchina in cui verrà eseguito Cassandra Adapter. Se utilizzi un service account, devi conoscere la posizione del file della chiave JSON (il file delle credenziali). Imposta la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS per specificare il percorso delle credenziali.

Per ulteriori informazioni, vedi:

Connetti l'adattatore Cassandra alla tua applicazione

L'adattatore Cassandra richiede le seguenti informazioni:

  • Nome progetto
  • Nome dell'istanza Spanner
  • Database a cui connettersi

Se utilizzi Docker, devi disporre del percorso di un file delle credenziali (file della chiave) in formato JSON.

Java in-process

  1. Se utilizzi un account di servizio per l'autenticazione, assicurati che la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS sia impostata sul percorso del file delle credenziali.

  2. Per le applicazioni Java, puoi collegare l'adattatore Cassandra all'applicazione direttamente aggiungendo google-cloud-spanner-cassandra come dipendenza al tuo progetto.

Per Maven, aggiungi la seguente nuova dipendenza nella sezione <dependencies>:

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

Per Gradle, aggiungi quanto segue:

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

  1. Modifica il codice di creazione CqlSession. Anziché utilizzare CqlSessionBuilder, utilizza SpannerCqlSessionBuilder e fornisci l'URI del database 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();
        }
      }
    }
    

Vai a In corso

Per le applicazioni Go, devi apportare una modifica di una riga al file di inizializzazione del cluster per integrare il client Go di Spanner Cassandra. A questo punto, puoi collegare l'adattatore Cassandra direttamente all'applicazione.

  1. Importa il pacchetto spanner dell'adattatore dal client Go di Spanner Cassandra nella tua applicazione Go.
import spanner "github.com/googleapis/go-spanner-cassandra/cassandra/gocql"
  1. Modifica il codice di creazione del cluster in modo da utilizzare spanner.NewCluster anziché gocql.NewCluster e fornisci l'URI del database 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
    }

Puoi configurare il cluster come di consueto dopo aver eseguito la connessione al database Spanner.

Autonoma

  1. Clona il repository:
git clone https://github.com/googleapis/go-spanner-cassandra.git
cd go-spanner-cassandra
  1. Esegui cassandra_launcher.go con il flag -db obbligatorio:
go run cassandra_launcher.go \
-db "projects/my_project/instances/my_instance/databases/my_database"
  1. Sostituisci -db con l'URI del database Spanner.

Docker

Avvia l'adattatore Cassandra con il seguente comando.

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

Il seguente elenco contiene le opzioni di avvio più utilizzate per l'adattatore Spanner Cassandra:

  • -db <DatabaseUri>

L'URI del database Spanner (obbligatorio). Specifica il database Spanner a cui si connette il client. Ad esempio, projects/YOUR_PROJECT/instances/YOUR_INSTANCE/databases/YOUR_DATABASE.

  • -tcp <TCPEndpoint>

L'indirizzo del listener proxy client. Definisce l'endpoint TCP in cui il client è in ascolto delle connessioni client Cassandra in entrata. Valore predefinito:localhost:9042

  • -grpc-channels <NumGrpcChannels>

Il numero di canali gRPC da utilizzare per connettersi a Spanner. Valore predefinito: 4

Ad esempio, il seguente comando avvia Cassandra Adapter sulla porta 9042 utilizzando le credenziali dell'applicazione e connette l'adattatore al database 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

Consigli

I seguenti consigli ti aiutano a migliorare la tua esperienza con l'adattatore Cassandra. Questi consigli si concentrano su Java, in particolare sul driver client Cassandra per Java versione 4.

Aumentare il timeout della richiesta

Un timeout della richiesta di cinque secondi o più offre un'esperienza migliore con l'adattatore Cassandra rispetto al valore predefinito di due secondi.

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

Ottimizzare il pool di connessioni

Le configurazioni predefinite per il numero massimo di connessioni e il numero massimo di richieste simultanee per connessione o host sono appropriate per ambienti di sviluppo, test e produzione o gestione temporanea a basso volume. Tuttavia, ti consigliamo di aumentare questi valori, poiché l'adattatore Cassandra si maschera da singolo nodo, a differenza di un pool di nodi all'interno del cluster Cassandra.

L'aumento di questi valori consente più connessioni simultanee tra il client e l'interfaccia Cassandra. In questo modo è possibile evitare l'esaurimento del pool di connessioni in caso di carico elevato.

# 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
  }
}

Ottimizzare i canali gRPC

I canali gRPC vengono utilizzati dal client Spanner per la comunicazione. Un canale gRPC equivale approssimativamente a una connessione TCP. Un canale gRPC può gestire fino a 100 richieste simultanee. Ciò significa che un'applicazione avrà bisogno di almeno tanti canali gRPC quanto il numero di richieste simultanee che eseguirà, diviso per 100.

Disattiva il routing basato su token

I driver che utilizzano il bilanciamento del carico basato su token potrebbero stampare un avviso o non funzionare quando utilizzano l'adattatore Cassandra. Poiché Cassandra Adapter si maschera da singolo nodo, non sempre funziona bene con i driver token-aware che prevedono la presenza di almeno un numero di nodi pari al fattore di replica nel cluster. Alcuni driver potrebbero stampare un avviso (che può essere ignorato) e tornare a un criterio di bilanciamento round robin, mentre altri driver potrebbero non funzionare e generare un errore. Per i driver che non funzionano e generano un errore, devi disattivare la funzionalità token-aware o configurare i criteri di bilanciamento del carico round robin.

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

Bloccare la versione del protocollo sulla V4

L'adattatore Cassandra è compatibile con qualsiasi driver client Apache Cassandra open source conforme al protocollo di trasferimento binario CQL v4. Assicurati di bloccare PROTOCOL_VERSION su V4, altrimenti potresti visualizzare errori di connessione.

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

Passaggi successivi