Share via


Migrazione in tempo reale ad Azure Istanza gestita per Apache Cassandra usando un proxy a doppia scrittura

Se possibile, è consigliabile usare la funzionalità nativa Apache Cassandra per eseguire la migrazione dei dati dal cluster esistente ad Azure Istanza gestita per Apache Cassandra configurando un cluster ibrido. Questa funzionalità usa il protocollo gossip di Apache Cassandra per replicare i dati dal data center di origine nel nuovo data center dell'istanza gestita in modo semplice. Tuttavia, potrebbero verificarsi alcuni scenari in cui la versione del database di origine non è compatibile oppure non è possibile configurare un cluster ibrido.

Questa esercitazione descrive come eseguire la migrazione dei dati ad Azure Istanza gestita per Apache Cassandra in modo live usando un proxy a doppia scrittura e Apache Spark. Il proxy a doppia scrittura viene usato per acquisire le modifiche in tempo reale, mentre i dati cronologici vengono copiati in blocco usando Apache Spark. I vantaggi di questo approccio sono:

  • Modifiche minime dell'applicazione. Il proxy può accettare connessioni dal codice dell'applicazione con poche o nessuna modifica alla configurazione. Instrada tutte le richieste al database di origine e instrada le scritture asincrone in una destinazione secondaria.
  • Dipendenza del protocollo di collegamento client. Poiché questo approccio non dipende da risorse back-end o protocolli interni, può essere usato con qualsiasi sistema Cassandra di origine o di destinazione che implementa il protocollo di collegamento Apache Cassandra.

L'immagine seguente illustra l'approccio.

Animazione che mostra la migrazione in tempo reale dei dati ad Azure Istanza gestita per Apache Cassandra.

Prerequisiti

Effettuare il provisioning di un cluster Spark

È consigliabile selezionare azure Databricks runtime versione 7.5, che supporta Spark 3.0.

Screenshot che mostra la ricerca della versione del runtime di Azure Databricks.

Aggiungere dipendenze Spark

È necessario aggiungere la libreria del connettore Apache Spark Cassandra al cluster per connettersi a qualsiasi endpoint Apache Cassandra compatibile con il protocollo di collegamento. Nel cluster selezionare Librerie>Installa nuovo>Maven e quindi aggiungere com.datastax.spark:spark-cassandra-connector-assembly_2.12:3.0.0 le coordinate Maven.

Importante

Se è necessario mantenere Apache Cassandra writetime per ogni riga durante la migrazione, è consigliabile usare questo esempio. Il file JAR di dipendenza in questo esempio contiene anche il connettore Spark, quindi è necessario installarlo anziché l'assembly del connettore precedente. Questo esempio è utile anche se si vuole eseguire una convalida del confronto di righe tra origine e destinazione dopo il completamento del caricamento cronologico dei dati. Per altri dettagli, vedere le sezioni "Eseguire il caricamento dei dati cronologici" e "convalidare l'origine e la destinazione".

Screenshot che mostra la ricerca di pacchetti Maven in Azure Databricks.

Selezionare Installa e quindi riavviare il cluster al termine dell'installazione.

Nota

Assicurarsi di riavviare il cluster Azure Databricks dopo l'installazione della libreria del connettore Cassandra.

Installare il proxy a doppio scrittura

Per prestazioni ottimali durante le operazioni di doppia scrittura, è consigliabile installare il proxy in tutti i nodi del cluster Cassandra di origine.

#assuming you do not have git already installed
sudo apt-get install git 

#assuming you do not have maven already installed
sudo apt install maven

#clone repo for dual-write proxy
git clone https://github.com/Azure-Samples/cassandra-proxy.git

#change directory
cd cassandra-proxy

#compile the proxy
mvn package

Avviare il proxy a doppia scrittura

È consigliabile installare il proxy in tutti i nodi del cluster Cassandra di origine. Eseguire almeno il comando seguente per avviare il proxy in ogni nodo. Sostituire <target-server> con un indirizzo IP o server da uno dei nodi del cluster di destinazione. Sostituire <path to JKS file> con il percorso di un file con estensione jks locale e sostituire <keystore password> con la password corrispondente.

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password>

L'avvio del proxy in questo modo presuppone che siano vere le condizioni seguenti:

  • Gli endpoint di origine e di destinazione hanno lo stesso nome utente e password.
  • Gli endpoint di origine e di destinazione implementano Secure Sockets Layer (SSL).

Se gli endpoint di origine e di destinazione non possono soddisfare questi criteri, leggere per altre opzioni di configurazione.

Configurare SSL

Per SSL, è possibile implementare un archivio chiavi esistente ,ad esempio quello usato dal cluster di origine, oppure creare un certificato autofirmato usando keytool:

keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048

È anche possibile disabilitare SSL per gli endpoint di origine o di destinazione se non implementano SSL. Usare i --disable-source-tls flag o --disable-target-tls :

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --source-port 9042 --target-port 10350 --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password> --target-username <username> --target-password <password> --disable-source-tls true  --disable-target-tls true 

Nota

Assicurarsi che l'applicazione client usi lo stesso archivio chiavi e la stessa password usati per il proxy a doppio scrittura quando si creano connessioni SSL al database tramite il proxy.

Configurare le credenziali e la porta

Per impostazione predefinita, le credenziali di origine verranno passate dall'app client. Il proxy userà le credenziali per stabilire connessioni ai cluster di origine e di destinazione. Come accennato in precedenza, questo processo presuppone che le credenziali di origine e di destinazione siano le stesse. Se necessario, è possibile specificare separatamente un nome utente e una password diversi per l'endpoint Cassandra di destinazione all'avvio del proxy:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password> --target-username <username> --target-password <password>

Le porte di origine e di destinazione predefinite, se non specificate, saranno 9042. Se la destinazione o l'endpoint Cassandra di origine viene eseguito su una porta diversa, è possibile usare --source-port o --target-port per specificare un numero di porta diverso:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --source-port 9042 --target-port 10350 --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password> --target-username <username> --target-password <password>

Distribuire il proxy in remoto

Potrebbero esserci circostanze in cui non si vuole installare il proxy nei nodi del cluster e si preferisce installarlo in un computer separato. In questo scenario è necessario specificare l'indirizzo IP di <source-server>:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar <source-server> <destination-server>

Avviso

Se si preferisce eseguire il proxy in remoto in un computer separato (anziché eseguirlo in tutti i nodi del cluster Apache Cassandra di origine), è consigliabile distribuire il proxy allo stesso numero di computer presenti nel cluster e configurare una sostituzione per i relativi indirizzi IP in system.peer usando la configurazione nel proxy indicato qui. In caso contrario, può influire sulle prestazioni durante la migrazione in tempo reale, perché il driver client non sarà in grado di aprire connessioni a tutti i nodi all'interno del cluster.

Consenti modifiche al codice dell'applicazione zero

Per impostazione predefinita, il proxy è in ascolto sulla porta 29042. Il codice dell'applicazione deve essere modificato in modo che punti a questa porta. Tuttavia, è possibile modificare la porta su cui è in ascolto il proxy. Questa operazione può essere eseguita se si desidera eliminare le modifiche al codice a livello di applicazione in base a:

  • L'esecuzione del server Cassandra di origine su una porta diversa.
  • Esecuzione del proxy sulla porta Cassandra standard 9042.
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042

Nota

L'installazione del proxy nei nodi del cluster non richiede il riavvio dei nodi. Tuttavia, se sono presenti molti client dell'applicazione e si preferisce che il proxy sia in esecuzione sulla porta Cassandra standard 9042 per eliminare eventuali modifiche al codice a livello di applicazione, è necessario modificare la porta predefinita di Apache Cassandra. È quindi necessario riavviare i nodi nel cluster e configurare la porta di origine come nuova porta definita per il cluster Cassandra di origine.

Nell'esempio seguente il cluster Cassandra di origine viene modificato in modo che venga eseguito sulla porta 3074 e si avvia il cluster sulla porta 9042:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042 --source-port 3074

Forzare i protocolli

Il proxy dispone di funzionalità per forzare i protocolli, che potrebbero essere necessari se l'endpoint di origine è più avanzato rispetto alla destinazione o non è altrimenti supportato. In tal caso, è possibile specificare --protocol-version e --cql-version forzare la conformità del protocollo alla destinazione:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --protocol-version 4 --cql-version 3.11

Dopo aver eseguito il proxy a doppio scrittura, è necessario modificare la porta nel client dell'applicazione e riavviare. In alternativa, modificare la porta Cassandra e riavviare il cluster se si è scelto questo approccio. Il proxy avvierà quindi l'inoltro delle scritture nell'endpoint di destinazione. È possibile ottenere informazioni sul monitoraggio e sulle metriche disponibili nello strumento proxy.

Eseguire il caricamento dei dati cronologici

Per caricare i dati, creare un notebook Scala nell'account Azure Databricks. Sostituire le configurazioni cassandra di origine e di destinazione con le credenziali corrispondenti e sostituire i keyspace e le tabelle di origine e di destinazione. Aggiungere altre variabili per ogni tabella in base alle esigenze nell'esempio seguente e quindi eseguire . Dopo che l'applicazione inizia a inviare richieste al proxy a doppio scrittura, è possibile eseguire la migrazione dei dati cronologici.

import com.datastax.spark.connector._
import com.datastax.spark.connector.cql._
import org.apache.spark.SparkContext

// source cassandra configs
val sourceCassandra = Map( 
    "spark.cassandra.connection.host" -> "<Source Cassandra Host>",
    "spark.cassandra.connection.port" -> "9042",
    "spark.cassandra.auth.username" -> "<USERNAME>",
    "spark.cassandra.auth.password" -> "<PASSWORD>",
    "spark.cassandra.connection.ssl.enabled" -> "true",
    "keyspace" -> "<KEYSPACE>",
    "table" -> "<TABLE>"
)

//target cassandra configs
val targetCassandra = Map( 
    "spark.cassandra.connection.host" -> "<Source Cassandra Host>",
    "spark.cassandra.connection.port" -> "9042",
    "spark.cassandra.auth.username" -> "<USERNAME>",
    "spark.cassandra.auth.password" -> "<PASSWORD>",
    "spark.cassandra.connection.ssl.enabled" -> "true",
    "keyspace" -> "<KEYSPACE>",
    "table" -> "<TABLE>",
    //throughput related settings below - tweak these depending on data volumes. 
    "spark.cassandra.output.batch.size.rows"-> "1",
    "spark.cassandra.output.concurrent.writes" -> "1000",
    "spark.cassandra.connection.remoteConnectionsPerExecutor" -> "1",
    "spark.cassandra.concurrent.reads" -> "512",
    "spark.cassandra.output.batch.grouping.buffer.size" -> "1000",
    "spark.cassandra.connection.keep_alive_ms" -> "600000000"
)

//set timestamp to ensure it is before read job starts
val timestamp: Long = System.currentTimeMillis / 1000

//Read from source Cassandra
val DFfromSourceCassandra = sqlContext
  .read
  .format("org.apache.spark.sql.cassandra")
  .options(sourceCassandra)
  .load
  
//Write to target Cassandra
DFfromSourceCassandra
  .write
  .format("org.apache.spark.sql.cassandra")
  .options(targetCassandra)
  .option("writetime", timestamp)
  .mode(SaveMode.Append)
  .save

Nota

Nell'esempio scala precedente si noterà che timestamp è impostato sull'ora corrente prima di leggere tutti i dati nella tabella di origine. writetime Viene quindi impostato su questo timestamp nascosto. Ciò garantisce che i record scritti dal caricamento dei dati cronologici nell'endpoint di destinazione non possano sovrascrivere gli aggiornamenti che vengono inseriti con un timestamp successivo dal proxy a doppia scrittura mentre i dati cronologici vengono letti.

Importante

Se è necessario mantenere i timestamp esatti per qualsiasi motivo, è consigliabile adottare un approccio di migrazione cronologica dei dati che mantiene i timestamp, ad esempio questo esempio. Il file JAR di dipendenza nell'esempio contiene anche il connettore Spark, quindi non è necessario installare l'assembly del connettore Spark indicato nei prerequisiti precedenti. Se entrambi sono installati nel cluster Spark, causeranno conflitti.

Convalidare l'origine e la destinazione

Al termine del caricamento dei dati cronologici, i database devono essere sincronizzati e pronti per il cutover. Tuttavia, è consigliabile convalidare l'origine e la destinazione per assicurarsi che corrispondano prima di finalmente tagliare.

Nota

Se è stato usato l'esempio di migrazione cassandra indicato in precedenza per conservare writetime, include la funzionalità di convalidare la migrazioneconfrontando le righe nell'origine e la destinazione in base a determinate tolleranze.

Passaggi successivi