Caricare e caricare in flussi dati con BigQuery Storage Write API
L'API BigQuery Storage Write è un'API unificata di importazione dati per BigQuery, Combina l'importazione di flussi e il caricamento in batch in un'unica API ad alte prestazioni. Puoi utilizzare l'API Storage Write per eseguire il flusso di record in BigQuery in tempo reale o per elaborare in batch un numero arbitrario di record e eseguirne il commit in un'unica operazione atomica.
Vantaggi dell'utilizzo dell'API Storage Write
semantica di consegna "exactly-once". L'API Storage Write supporta la
semantica "exactly-once" attraverso l'uso degli offset di flusso. A differenza del metodo tabledata.insertAll
, l'API Storage Write non scrive mai due messaggi con lo stesso offset all'interno di un flusso, se il client fornisce offset dello stream quando aggiunge record.
Transazioni a livello di stream. Puoi scrivere dati in un flusso e impegnarli in un'unica transazione. Se l'operazione di commit non va a buon fine, puoi riprovare a eseguirla in sicurezza.
Transazioni tra gli stream. Più worker possono creare i propri flussi per elaborare i dati in modo indipendente. Quando tutti i worker sono stati completati, puoi eseguire il commit di tutti gli stream come transazione.
Protocollo efficiente. L'API Storage Write è più efficiente
del vecchio metodo insertAll
perché utilizza lo streaming gRPC anziché REST
tramite HTTP. L'API Storage Write supporta anche i formati binari sotto forma di buffer di protocollo, che sono un formato di cavo più efficiente rispetto a JSON.
Le richieste di scrittura sono asincrone con l'ordine garantito.
Rilevamento dell'aggiornamento dello schema. Se lo schema della tabella sottostante cambia mentre il client è in streaming, l'API Storage Write informa il client. Il client può decidere se riconnettersi utilizzando lo schema aggiornato o continuare a scrivere nella connessione esistente.
Costo inferiore. L'API Storage Write ha un costo notevolmente inferiore
rispetto alla precedente API di streaming insertAll
. Inoltre, puoi importare gratuitamente fino a 2 TB al mese.
Autorizzazioni obbligatorie
Per utilizzare l'API Storage Write, devi disporre delle autorizzazioni bigquery.tables.updateData
.
I seguenti ruoli IAM predefiniti di Identity and Access Management includono le autorizzazioni bigquery.tables.updateData
:
bigquery.dataEditor
bigquery.dataOwner
bigquery.admin
Per ulteriori informazioni sulle autorizzazioni e sui ruoli IAM in BigQuery, consulta Autorizzazioni e ruoli predefiniti.
Panoramica dell'API Storage Write
L'astrazione di base nell'API Storage Write è uno stream. Uno stream scrive i dati in una tabella BigQuery. Più di un flusso può scrivere contemporaneamente alla stessa tabella.
Stream predefinito
L'API Storage Write fornisce uno stream predefinito progettato per gli scenari di streaming in cui disponi di dati in arrivo continuo. Ha le seguenti caratteristiche:
- I dati scritti nel flusso predefinito sono disponibili immediatamente per la query.
- Lo stream predefinito supporta la semantica "almeno una volta".
- Non devi creare esplicitamente lo stream predefinito.
Se stai eseguendo la migrazione dall'API precedente tabledata.insertall
, valuta la possibilità di utilizzare lo stream predefinito. Ha una semantica di scrittura simile, con una maggiore resilienza dei dati e meno restrizioni di scalabilità.
Flusso API:
AppendRows
(loop)
Per ulteriori informazioni e codice di esempio, consulta Utilizzare lo stream predefinito per la semantica almeno una volta.
Stream creati dall'applicazione
Puoi creare uno stream in modo esplicito se hai bisogno di uno dei seguenti comportamenti:
- Scrivi la semantica esattamente una volta attraverso l'uso degli offset del flusso.
- Supporto di ulteriori proprietà ACID.
In generale, gli stream creati dall'applicazione offrono un maggiore controllo sulle funzionalità a scapito di una maggiore complessità.
Quando crei un flusso, specifichi un tipo. Il tipo controlla quando i dati scritti nel flusso diventano visibili in BigQuery per la lettura.
Tipo in attesa
In tipo in attesa, i record vengono salvati nel buffer in attesa finché non comprimi il flusso. Quando esegui il commit di un flusso, tutti i dati in attesa diventano disponibili per la lettura. Il commit è un'operazione atomica. Utilizza questo tipo per i carichi di lavoro batch, in alternativa ai job di carico BigQuery. Per ulteriori informazioni, consulta Caricare in batch i dati utilizzando l'API Storage Write.
Flusso API:
Tipo di commit
In tipo di commit, i record sono disponibili per la lettura immediatamente quando li scrivi nel flusso. Utilizza questo tipo per i carichi di lavoro di streaming che richiedono una latenza di lettura minima. Lo stream predefinito utilizza sempre il tipo di commit. Puoi creare uno stream di tipo commit se hai bisogno della semantica "exactly-once". Per ulteriori informazioni, consulta la pagina relativa all'uso del tipo di commit per la semantica "exactly-once".
Flusso API:
CreateWriteStream
AppendRows
(loop)FinalizeWriteStream
(facoltativo)
Tipo di buffering
Il tipo di buffer è un tipo avanzato che in genere non deve essere utilizzato, tranne che con il connettore I/O BigQuery Apache Beam. Se hai batch di piccole dimensioni che vuoi garantire che vengano visualizzati insieme, utilizza il tipo impegnato e invia ogni batch in un'unica richiesta. In questo tipo vengono forniti i commit a livello di riga e il buffer viene registrato finché le righe non vengono sottoposte a commit, svuotando il flusso.
Flusso API:
CreateWriteStream
AppendRows
≥FlushRows
(loop)FinalizeWriteStream
(facoltativo)
Selezione di un tipo
Utilizza il seguente diagramma di flusso per decidere quale sia il tipo migliore per il tuo carico di lavoro:
Dettagli API
Quando utilizzi l'API Storage Write, tieni presente quanto segue:
AppendRow
Il metodo AppendRows
aggiunge uno o più record allo stream. La prima
chiamata a AppendRows
deve contenere un nome di flusso insieme allo schema dei dati,
specificato come DescriptorProto
. Come best practice, invia un gruppo di righe in ogni chiamata AppendRows
. Non inviare una riga alla volta.
Gestione proto-buffer
I buffer di protocollo forniscono un meccanismo estensibile, indipendente dalla piattaforma e basato sul linguaggio per la serializzazione dei dati strutturati in modo compatibile con l'inoltro e con la versione precedente. Sono vantaggiosi perché offrono un'archiviazione di dati compatta con analisi rapide ed efficienti. Per scoprire di più sui buffer di protocollo, consulta la panoramica del buffer di protocollo.
Se intendi utilizzare l'API direttamente con un messaggio di buffer di protocollo predefinito, il messaggio di buffer di protocollo non può utilizzare uno specificatore package
e tutti i tipi nidificati o di enumerazione devono essere definiti all'interno del messaggio principale di primo livello.
I riferimenti a messaggi esterni non sono consentiti. Per un esempio, consulta sample_data.proto.
I client Java e Go supportano i buffer di protocollo arbitrarii, perché la libreria client normalizza lo schema di buffer di protocollo.
Finalizza scrittura flusso
Il metodo FinalizeWriteStream
finalizza il flusso in modo che non possa essere aggiunto nessun nuovo dato. Questo metodo è obbligatorio nel tipo Pending
e facoltativo nei tipi Committed
e Buffered
. Lo stream predefinito non supporta questo metodo.
Gestione degli errori
Se si verifica un errore, google.rpc.Status
può includere un elemento StorageError
nei dettagli dell'errore. Consulta la pagina StorageErrorCode
per trovare il tipo di errore specifico. Per scoprire di più sul modello di errore delle API di Google, consulta la sezione Errori.
Connessioni
L'API Storage Write è un'API gRPC che utilizza connessioni
direzionali. Il metodo AppendRows
crea una connessione a uno stream. Puoi aprire più connessioni nello stream predefinito. Queste aggiunte sono asincrone,
il che ti consente di inviare una serie di scritture contemporaneamente. I messaggi di risposta su ciascuna connessione bidirezionale arrivano nello stesso ordine in cui sono state inviate le richieste.
I flussi creati dall'applicazione possono avere una sola connessione attiva. Come best practice, limita il numero di connessioni attive e utilizza una connessione per il maggior numero possibile di scritture di dati.
In genere, una singola connessione supporta una velocità effettiva di almeno 1 MBps. Il limite superiore dipende da diversi fattori, ad esempio la larghezza di banda della rete, lo schema dei dati e il carico del server, ma possono superare i 10 MBps. Quando una connessione raggiunge un limite di velocità effettiva, le richieste in entrata possono essere rifiutate o messe in coda fino a quando il numero di richieste in corso non diminuisce. Se hai bisogno di una velocità effettiva superiore, crea più connessioni.
BigQuery chiude la connessione gRPC se la connessione rimane
inattiva per troppo tempo. In questo caso, il codice di risposta è HTTP 409
. La connessione gRPC può essere chiusa anche in caso di riavvio del server o per altri motivi. Se si verifica un errore di connessione, crea una nuova connessione. Le librerie client Java e Go si riconnettono automaticamente se la connessione viene chiusa.
Supporto libreria client
Puoi utilizzare l'API Storage Write chiamando direttamente l'API gRPC o utilizzando una delle librerie client, disponibili per Java, Python e Go. In generale, ti consigliamo di utilizzare una libreria client, che offre un'interfaccia di programmazione più semplice e gestisce l'RPC di streaming bidirezionale sottostante per te.
Client Java
La libreria client Java fornisce due oggetti writer:
StreamWriter
: accetta i dati nel formato di buffer di protocollo.JsonStreamWriter
: accetta i dati in formato JSON e li converte in buffer di protocollo prima di inviarli tramite cavo.JsonStreamWriter
supporta anche gli aggiornamenti automatici dello schema. Se lo schema della tabella cambia, l'autore si riconnette automaticamente al nuovo schema, consentendo al client di inviare i dati utilizzando il nuovo schema.
Il modello di programmazione è simile per entrambi gli autori. La differenza principale è il modo in cui formatti il payload.
L'oggetto writer gestisce una connessione all'API Storage Write. L'oggetto writer pulisce automaticamente le richieste, aggiunge le intestazioni di routing a livello di richiesta alle richieste e si riconnette dopo gli errori di connessione. Se utilizzi direttamente l'API gRPC, devi gestire questi dettagli.
Client Python
Il client Python è un client di livello inferiore che aggrega l'API gRPC. Per utilizzare questo client, devi inviare i dati come buffer di protocollo, come descritto nella sezione Flusso API.
Per scoprire di più sull'utilizzo dei buffer di protocollo con Python, consulta il Tutorial sulle nozioni di base di buffer di protocollo in Python.
Client Go
Il client Go utilizza un'architettura client-server per codificare i messaggi nel formato di buffer di protocollo utilizzando proto2. Per dettagli su come utilizzare il client Go, con il codice di esempio, consulta la documentazione di Go.Conversioni dei tipi di dati
La seguente tabella mostra i tipi di buffer di protocollo supportati per ogni tipo di dati BigQuery:
Tipo di dati BigQuery | Tipi di buffer di protocollo supportati |
---|---|
BOOL |
bool , int32 , int64 , uint32 e uint64 |
BYTES |
bytes , string |
DATE |
int32 (opzione preferita), int64
Il valore è il numero di giorni dall'epoca Unix (1970-01-01). L'intervallo valido è compreso tra "-719162" (0001-01-01) e "2932896" (9999-12-31). |
DATETIME , TIME |
string
|
int64
Utilizza la classe
|
|
FLOAT |
double , float |
GEOGRAPHY |
string
Il valore è una geometria in formato WKT o GeoJson. |
INTEGER |
int32 , int64 , uint32 ,
enum , google.protobuf.Int32Value ,
google.protobuf.Int64Value ,
google.protobuf.UInt32Value |
JSON |
string |
NUMERIC , BIGNUMERIC |
int32 , int64 , uint32 , uint64 , double , float e string |
bytes Utilizza la classe
|
|
STRING |
string , enum , google.protobuf.StringValue |
TIME |
string
Il valore deve essere un
valore letterale |
TIMESTAMP |
int64 (consigliato), int32 ,
uint32 , google.protobuf.Timestamp
Il valore è espresso in microsecondi dal periodo Unix (1970-01-01). |
REPEATED FIELD |
array
Un tipo di array nel protocollo corrisponde a un campo ripetuto in BigQuery. |
RECORD |
message
Un tipo di messaggio nidificato nel protocollo corrisponde a un campo di record in BigQuery. |
Partizionamento delle colonne delle unità di tempo
Puoi trasmettere i dati in una tabella partizionata su una colonna DATE
, DATETIME
o TIMESTAMP
compresa tra 5 anni fa e 1 anno dopo.
I dati che non rientrano in questo intervallo vengono rifiutati.
Quando i dati vengono trasmessi in streaming, vengono inseriti inizialmente nella partizione __UNPARTITIONED__
. Dopo aver raccolto un numero sufficiente di dati non partizionati, BigQuery esegue il nuovo partizionamento dei dati, posizionandoli nella partizione appropriata.
Tuttavia, non esiste un accordo sul livello del servizio (SLA) che definisce il tempo necessario per trasferire i dati dalla partizione __UNPARTITIONED__
.
L'API Storage Write non supporta l'utilizzo di decoratori della partizione.
Metriche dell'API Storage Write
Per le metriche sul monitoraggio dell'importazione dati con l'API Storage Write, come la latenza lato server, le connessioni simultanee, i byte caricati e le righe caricate, consulta Metriche Google Cloud.
Limitazioni relative al Data Manipulation Language (DML)
Non puoi utilizzare le istruzioni UPDATE
, DELETE
o MERGE
per modificare le righe che sono state scritte in una tabella dall'API BigQuery Storage Write negli ultimi 30 minuti.
Puoi utilizzare queste istruzioni per modificare tutte le altre righe.
Quote dell'API Storage Write
Per informazioni sulle quote e sui limiti dell'API Storage Write, consulta Quote e limiti dell'API Storage Storage di BigQuery.
Puoi monitorare le connessioni simultanee e l'utilizzo della quota di velocità effettiva nella pagina Quote di Google Cloud Console.
Prezzi dell'API Storage Write
Per i prezzi, vedi Prezzi di importazione dati.
Passaggi successivi
- Trasmettere flussi di dati utilizzando l'API Storage Write
- Caricare i dati in batch utilizzando l'API Storage Write
- Best practice per l'API Storage Write