Questa pagina descrive come utilizzare il connettore Dataflow per Spanner per importare, esportare e modificare i dati nei database Spanner con dialetto GoogleSQL e nei database con dialetto PostgreSQL.
Dataflow è un servizio gestito per la trasformazione e l'arricchimento dei dati. Il connettore Dataflow per Spanner ti consente di leggere e scrivere dati in Spanner in una pipeline Dataflow, eventualmente trasformandoli o modificandoli. 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 entrata e in uscita da Spanner. È anche il metodo consigliato per eseguire trasformazioni di grandi dimensioni in un database che non sono supportate dalla DML partizionata, come i trasferimenti di tabelle ed eliminazioni collettive che richiedono un JOIN. Quando lavori con singoli database, puoi utilizzare altri metodi 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 nuovamente un database 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 anche utilizzando il formato Avro.
Il connettore Dataflow per Spanner fa parte dell'SDK Apache Beam per 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 e le trasformazioni PCollection
, consulta la guida alla programmazione di Apache Beam.
Aggiungi il connettore al progetto Maven
Per aggiungere il Google Cloud connettore Dataflow a un progetto Maven, aggiungi l'elemento Maven beam-sdks-java-io-google-cloud-platform
al file pom.xml
come dipendenza.
Ad esempio, supponendo che il file pom.xml
imposti beam.version
sul numero di versione appropriato, devi aggiungere la seguente dipendenza:
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-sdks-java-io-google-cloud-platform</artifactId>
<version>${beam.version}</version>
</dependency>
Leggere 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 vista coerente dei dati mediante un'attenta lettura. Se non specifichi diversamente, viene acquisito uno snapshot del risultato della lettura al momento dell'avvio della lettura. Consulta la sezione letture per ulteriori informazioni sui diversi tipi di letture che Spanner può eseguire.
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 un nome tabella utilizzando il metodo SpannerIO.Read.withTable
e 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 principali da leggere utilizzando il metodo
SpannerIO.Read.withKeySet
.
Puoi anche leggere una tabella utilizzando un indice secondario specificato. Come per la
chiamata all'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 contenente i valori delle colonne necessari utilizzando il metodo SpannerIO.Read.withIndex
. L'indice deve memorizzare tutte le colonne che la trasformazione deve leggere. La chiave primaria della tabella di base viene memorizzata implicitamente. Ad esempio, per leggere la tabella Songs
utilizzando l'indice
SongsBySongName
, utilizza il
seguente codice:
GoogleSQL
PostgreSQL
Controllare l'inattività dei dati sulle transazioni
È garantito che una trasformazione venga eseguita su un'istantanea coerente dei dati. Per controllare l'obsolescenza dei dati, utilizza il metodo SpannerIO.Read.withTimestampBound
. Per ulteriori informazioni, consulta la sezione Transazioni.
Leggere da più tabelle nella stessa transazione
Se vuoi leggere i dati da più tabelle nello stesso istante per garantire la coerenza dei dati, esegui tutte le letture in una singola 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
Leggere i dati da tutte le tabelle disponibili
Puoi leggere i dati da tutte le tabelle disponibili in un database Spanner.
GoogleSQL
PostgreSQL
Risolvere 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 provi a 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 Informazioni su 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 una unione distribuita come primo operatore nel piano di esecuzione della query. Rimuovi le funzioni aggregate, le unioni di tabelle e gli operatori DISTINCT
, GROUP BY
e ORDER
, in quanto sono gli operatori che hanno maggiori probabilità di impedire il funzionamento della query.
Creare 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 "at-least-once", il che significa che la mutazione potrebbe essere scritta più volte. Di conseguenza, solo le mutazioni INSERT
potrebbero generare
com.google.cloud.spanner.SpannerException: ALREADY_EXISTS
errori che causano
il fallimento della pipeline. Per evitare questo errore, utilizza 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 mutazioni delle righe di input. Il connettore Dataflow raggruppa
le mutazioni in batch per maggiore efficienza.
L'esempio seguente mostra come applicare una trasformazione di scrittura a un PCollection
di
mutazioni:
GoogleSQL
PostgreSQL
Se una trasformazione si interrompe in modo imprevisto prima del completamento, le mutazioni già applicate non vengono annullate.
Applicare 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 ripetuta.
I gruppi di mutazioni hanno il rendimento migliore quando vengono utilizzati per raggruppare le mutazioni che influiscono sui dati archiviati vicini nello spazio delle chiavi. Poiché Spanner interseca i dati delle tabelle principali e secondarie nella tabella principale, 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 i dati vicini nello spazio delle chiavi. Per ulteriori informazioni su come Spanner memorizza i dati delle tabelle principali e secondarie, consulta Schema e modello di dati. Se non organizzi i gruppi di mutazioni in base alle gerarchie di tabelle consigliate o se i dati a cui viene eseguito l'accesso non sono vicini nello spazio delle chiavi, Spanner potrebbe dover eseguire commit in due fasi, con conseguente rallentamento delle prestazioni. Per ulteriori informazioni, consulta Compromisi relativi alla 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 viene creato un MutationGroup
, la prima mutazione elencata diventa la mutazione principale. Se il gruppo di mutazioni interessa sia una tabella principale che una tabella figlia, la mutazione principale deve essere una mutazione della tabella principale. In caso contrario,
puoi utilizzare qualsiasi mutazione come mutazione principale. Il connettore Dataflow utilizza la mutazione principale per determinare i confini della partizione in modo da raggruppare in modo efficiente le mutazioni.
Ad esempio, immagina che la tua applicazione monitori il comportamento e segnali per la revisione il comportamento problematico degli utenti. Per ogni comportamento segnalato, devi actualizare 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 principale chiara. Abbiamo selezionato userMutation
come principale collocandolo per primo. L'applicazione delle due mutazioni separatamente sarebbe più rapida, ma
non garantirebbe l'atomicità, pertanto 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 console Google Cloud utilizzando Dataflow.