Questa pagina descrive come utilizzare il connettore Dataflow per Spanner per importare, esportare e modificare i dati nei database di dialetti GoogleSQL e PostgreSQL di Spanner.
Dataflow è un servizio gestito per la trasformazione e l'arricchimento dei dati. Il connettore Dataflow per Spanner consente di leggere i dati da Spanner e scriverli in una pipeline Dataflow, trasformandoli o modificandoli, se necessario. Puoi anche creare pipeline che trasferiscono dati tra Spanner e altri prodottiGoogle Cloud .
Il connettore Dataflow è il metodo consigliato per spostare in modo efficiente i dati in blocco da e verso Spanner. È anche il metodo consigliato per eseguire trasformazioni di grandi dimensioni a un database che non sono supportate da DML partizionate, come spostamenti di tabelle ed eliminazioni collettive che richiedono un'operazione JOIN. Quando lavori con singoli database, esistono altri metodi che puoi utilizzare per importare ed esportare i dati:
- Utilizza la console Google Cloud per esportare un singolo database da Spanner a Cloud Storage in formato Avro.
- Utilizza la console Google Cloud per importare un database di nuovo in Spanner dai file esportati in Cloud Storage.
- Utilizza l'API REST o Google Cloud CLI per eseguire job di esportazione o importazione da Spanner a Cloud Storage e viceversa utilizzando anche il formato Avro.
Il connettore Dataflow per Spanner fa parte dell'SDK Apache Beam Java e fornisce un'API per eseguire le azioni precedenti. Per saperne di più su alcuni dei concetti trattati in questa pagina, come gli oggetti PCollection e le trasformazioni, consulta la guida alla programmazione di Apache Beam.
Aggiungere il connettore al progetto Maven
Per aggiungere il connettore Dataflow a un progetto Maven, aggiungi l'artefatto Maven beam-sdks-java-io-google-cloud-platform al file pom.xml come dipendenza. Google Cloud
Ad esempio, supponendo che il file pom.xml imposti beam.version sul
numero di versione appropriato, aggiungeresti la seguente dipendenza:
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-sdks-java-io-google-cloud-platform</artifactId>
<version>${beam.version}</version>
</dependency>
Leggi i dati da Spanner
Per leggere da Spanner, applica la trasformazione SpannerIO.read. Configura la lettura utilizzando i metodi della classe
SpannerIO.Read. L'applicazione della trasformazione restituisce un
PCollection<Struct>, in cui ogni elemento della raccolta
rappresenta una singola riga restituita dall'operazione di lettura. Puoi leggere da
Spanner con e senza una query SQL specifica, a seconda dell'output
necessario.
L'applicazione della trasformazione SpannerIO.read restituisce una visualizzazione coerente dei dati
eseguendo una lettura coerente. Se non specifichi diversamente, il risultato della lettura
viene acquisito al momento dell'inizio della lettura. Per saperne di più sui diversi tipi di letture che Spanner può eseguire, consulta la sezione Letture.
Leggere i dati utilizzando una query
Per leggere un insieme specifico di dati da Spanner, configura la trasformazione utilizzando il metodo SpannerIO.Read.withQuery per specificare una query SQL. Ad esempio:
Leggere i dati senza specificare una query
Per leggere da un database senza utilizzare una query, puoi specificare il nome di una tabella utilizzando il metodo SpannerIO.Read.withTable e specificare un elenco di colonne da leggere utilizzando il metodo SpannerIO.Read.withColumns. Ad esempio:
GoogleSQL
PostgreSQL
Per limitare le righe lette, puoi specificare un insieme di chiavi primarie da leggere utilizzando il metodo
SpannerIO.Read.withKeySet.
Puoi anche leggere una tabella utilizzando un indice secondario specificato. Come per la
chiamata API readUsingIndex,
l'indice deve contenere tutti i dati visualizzati nei risultati della query.
A questo scopo, specifica la tabella come mostrato nell'esempio precedente e specifica l'indice che contiene i valori delle colonne necessari utilizzando il metodo SpannerIO.Read.withIndex. L'indice deve archiviare tutte le colonne che la trasformazione deve leggere. La chiave primaria della tabella di base è
memorizzata implicitamente. Ad esempio, per leggere la tabella Songs utilizzando l'indice
SongsBySongName, utilizza il
seguente codice:
GoogleSQL
PostgreSQL
Controllare l'inattività dei dati delle transazioni
È garantito che una trasformazione venga eseguita su un'istantanea coerente dei dati. Per
controllare la freschezza dei dati, utilizza il
metodo SpannerIO.Read.withTimestampBound. Per saperne di più, consulta la sezione
Transazioni.
Leggere da più tabelle nella stessa transazione
Se vuoi leggere i dati da più tabelle nello stesso momento per garantire la coerenza dei dati, esegui tutte le letture in un'unica transazione. Per farlo, applica una trasformazione createTransaction, creando un oggetto PCollectionView<Transaction> che poi crea una transazione. La
visualizzazione risultante può essere passata a un'operazione di lettura utilizzando
SpannerIO.Read.withTransaction.
GoogleSQL
PostgreSQL
Leggi i dati da tutte le tabelle disponibili
Puoi leggere i dati da tutte le tabelle disponibili in un database Spanner.
GoogleSQL
PostgreSQL
Risolvi i problemi relativi alle query non supportate
Il connettore Dataflow supporta solo le query SQL di Spanner in cui il primo operatore nel piano di esecuzione della query è un'unione distribuita. Se tenti di leggere i dati da Spanner utilizzando una query e ricevi un'eccezione che indica che la query does not have a
DistributedUnion at the root, segui i passaggi descritti in Comprendere come Spanner esegue le query per recuperare un piano di esecuzione per la query utilizzando la console Google Cloud .
Se la query SQL non è supportata, semplificala in una query che abbia un'unione distribuita come primo operatore nel piano di esecuzione della query. Rimuovi le funzioni di aggregazione, le unioni di tabelle e gli operatori DISTINCT, GROUP BY e ORDER, in quanto sono gli operatori che più probabilmente impediscono il funzionamento della query.
Crea mutazioni per una scrittura
Utilizza il metodo newInsertOrUpdateBuilder della classe Mutation anziché il metodo newInsertBuilder, a meno che non sia assolutamente necessario per le pipeline Java. Per le pipeline Python, utilizza
SpannerInsertOrUpdate anziché
SpannerInsert. Dataflow fornisce
garanzie di consegna "at-least-once", il che significa che la mutazione potrebbe essere scritta
più volte. Di conseguenza, solo le mutazioni di INSERT potrebbero generare errori com.google.cloud.spanner.SpannerException: ALREADY_EXISTS che causano l'interruzione della pipeline. Per evitare questo errore, utilizza invece la mutazione INSERT_OR_UPDATE, che aggiunge una nuova riga o aggiorna i valori delle colonne se la riga esiste già. La mutazione INSERT_OR_UPDATE può essere applicata più di una volta.
Scrivere in Spanner e trasformare i dati
Puoi scrivere dati in Spanner con il connettore Dataflow utilizzando una trasformazione SpannerIO.write per eseguire una raccolta di modifiche alle righe di input. Il connettore Dataflow raggruppa
le mutazioni in batch per efficienza.
L'esempio seguente mostra come applicare una trasformazione di scrittura a un PCollection di mutazioni:
GoogleSQL
PostgreSQL
Se una trasformazione si interrompe inaspettatamente prima del completamento, le mutazioni già applicate non vengono ripristinate.
Applica gruppi di mutazioni in modo atomico
Puoi utilizzare la classe MutationGroup per assicurarti che un
gruppo di mutazioni venga applicato insieme in modo atomico. Le mutazioni in un
MutationGroup vengono inviate nella stessa transazione, ma la
transazione potrebbe essere ritentata.
I gruppi di mutazioni funzionano meglio se vengono utilizzati per raggruppare le mutazioni che influiscono sui dati archiviati in prossimità nello spazio delle chiavi. Poiché Spanner interleave i dati delle tabelle padre e figlio nella tabella padre, questi dati sono sempre vicini nello spazio delle chiavi. Ti consigliamo di strutturare il gruppo di mutazioni in modo che contenga una mutazione applicata a una tabella principale e mutazioni aggiuntive applicate alle tabelle secondarie oppure in modo che tutte le mutazioni modifichino dati vicini nello spazio delle chiavi. Per saperne di più su come Spanner archivia i dati delle tabelle padre e figlio, consulta Schema e modello dei dati. Se non organizzi i gruppi di mutazioni in base alle gerarchie di tabelle consigliate o se i dati a cui si accede non sono vicini nello spazio delle chiavi, Spanner potrebbe dover eseguire commit in due fasi, il che comporta prestazioni più lente. Per saperne di più, consulta Compromessi sulla località.
Per utilizzare MutationGroup, crea una trasformazione SpannerIO.write e chiama il metodo SpannerIO.Write.grouped, che restituisce una trasformazione che puoi poi applicare a un PCollection di oggetti MutationGroup.
Quando crei un MutationGroup, la prima mutazione elencata diventa la
mutazione principale. Se il gruppo di mutazioni interessa sia una tabella padre che una tabella figlio, la mutazione principale deve essere una mutazione della tabella padre. Altrimenti,
puoi utilizzare qualsiasi mutazione come mutazione principale. Il connettore Dataflow
utilizza la mutazione principale per determinare i limiti delle partizioni al fine
di raggruppare in batch le mutazioni in modo efficiente.
Ad esempio, supponiamo che la tua applicazione monitori il comportamento e contrassegni
il comportamento problematico degli utenti per la revisione. Per ogni comportamento segnalato, devi
aggiornare la tabella Users per bloccare l'accesso dell'utente alla tua applicazione e devi
anche registrare l'incidente nella tabella PendingReviews. Per assicurarti che entrambe le tabelle vengano aggiornate in modo atomico, utilizza un MutationGroup:
GoogleSQL
PostgreSQL
Quando crei un gruppo di mutazioni, la prima mutazione fornita come argomento
diventa la mutazione principale. In questo caso, le due tabelle non sono correlate, quindi
non esiste una mutazione primaria chiara. Abbiamo selezionato userMutation come principale
posizionandolo per primo. L'applicazione delle due mutazioni separatamente sarebbe più veloce, ma
non garantirebbe l'atomicità, quindi il gruppo di mutazioni è la scelta migliore in questa
situazione.
Passaggi successivi
- Scopri di più sulla progettazione di una pipeline di dati Apache Beam.
- Esporta e importa i database Spanner nella consoleGoogle Cloud utilizzando Dataflow.