Introduzione all'API BigQuery Storage Write
L'API BigQuery Storage Write è un'API unificata di importazione dati per BigQuery. che combina l'importazione di flussi di dati e il caricamento in batch in un'unica API ad alte prestazioni. Puoi utilizzare l'API Storage Write per trasmettere record in streaming in BigQuery in tempo reale o per elaborare in batch un numero arbitrariamente elevato di record e eseguirne il commit in una singola operazione atomica.
Vantaggi dell'utilizzo dell'API Storage Write
Semantica di consegna "exactly-once". L'API Storage Write supporta
la semantica "exactly-once" tramite l'utilizzo di 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 di flusso durante l'aggiunta di record.
Transazioni a livello di stream. Puoi scrivere dati in uno stream e eseguirne il commit come singola transazione. Se l'operazione di commit non va a buon fine, puoi riprovare in tutta sicurezza.
Transazioni tra stream. Più lavoratori possono creare i propri stream per elaborare i dati in modo indipendente. Quando tutti i worker hanno terminato, puoi eseguire il commit di tutti gli stream come transazione.
Protocollo efficiente. L'API Storage Write è più efficiente del metodo insertAll
legacy perché utilizza lo streaming gRPC anziché REST su HTTP. L'API Storage Write supporta anche il formato binario protocol buffer e il formato colonnare Apache Arrow, che sono formati di trasferimento più efficienti rispetto a JSON. Le richieste di scrittura sono asincrone
con ordinamento garantito.
Rilevamento aggiornamenti dello schema. Se lo schema della tabella sottostante cambia durante lo streaming del client, l'API Storage Write invia una notifica al 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 fino a 2 TiB al mese gratuitamente.
Autorizzazioni obbligatorie
Per utilizzare l'API Storage Write, devi disporre delle autorizzazioni
bigquery.tables.updateData
.
I seguenti ruoli IAM (Identity and Access Management) predefiniti includono le autorizzazioni bigquery.tables.updateData
:
bigquery.dataEditor
bigquery.dataOwner
bigquery.admin
Per saperne di più sui ruoli e sulle autorizzazioni IAM in BigQuery, consulta Ruoli e autorizzazioni predefiniti.
Ambiti di autenticazione
L'utilizzo dell'API Storage Write richiede uno dei seguenti ambiti OAuth:
https://www.googleapis.com/auth/bigquery
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/bigquery.insertdata
Per ulteriori informazioni, consulta la panoramica dell'autenticazione.
Panoramica dell'API Storage Write
L'astrazione principale nell'API Storage Write è uno stream. Un flusso scrive i dati in una tabella BigQuery. Più di uno stream può scrivere contemporaneamente nella stessa tabella.
Stream predefinito
L'API Storage Write fornisce uno stream predefinito, progettato per scenari di streaming in cui i dati arrivano continuamente. Ha le seguenti caratteristiche:
- I dati scritti nel flusso predefinito sono immediatamente disponibili per le query.
- Il flusso predefinito supporta la semantica "at-least-once".
- Non è necessario creare esplicitamente lo stream predefinito.
Se esegui la migrazione dall'API legacy
tabledata.insertall
, valuta la possibilità di
utilizzare lo stream predefinito. Ha una semantica di scrittura simile, con una maggiore resilienza dei dati e meno limitazioni di scalabilità.
Flusso API:
AppendRows
(loop)
Per ulteriori informazioni e un esempio di codice, consulta Utilizzare lo stream predefinito per la semantica at-least-once.
Stream creati dalle applicazioni
Puoi creare esplicitamente uno stream se hai bisogno di uno dei seguenti comportamenti:
- Semantica di scrittura esattamente una volta tramite l'utilizzo di offset di stream.
- Supporto per ulteriori proprietà ACID.
In generale, i flussi creati dalle applicazioni offrono un maggiore controllo sulle funzionalità a costo di una maggiore complessità.
Quando crei uno stream, specifichi un tipo. Il tipo controlla quando i dati scritti nello stream diventano visibili in BigQuery per la lettura.
Tipo in attesa
Nel tipo in attesa, i record vengono memorizzati nel buffer in uno stato in attesa finché non commit lo stream. Quando esegui il commit di uno stream, tutti i dati in attesa diventano disponibili per la lettura. Il commit è un'operazione atomica. Utilizza questo tipo per i workload batch, in alternativa ai job di caricamento BigQuery. Per maggiori informazioni, consulta Caricare i dati in batch utilizzando l'API Storage Write.
Flusso API:
Tipo di impegno
Nel tipo di commit, i record sono disponibili per la lettura immediatamente mentre 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 un tipo di commit almeno una volta. Per saperne di più, consulta Utilizzare il tipo di impegno per la semantica exactly-once.
Flusso API:
CreateWriteStream
AppendRows
(loop)FinalizeWriteStream
(facoltativo)
Tipo memorizzato nel buffer
Il tipo bufferizzato è un tipo avanzato che in genere non deve essere utilizzato, tranne che con il connettore BigQuery I/O di Apache Beam. Se hai piccoli batch che vuoi garantire che vengano visualizzati insieme, utilizza il tipo committed e invia ogni batch in una richiesta. In questo tipo, vengono forniti commit a livello di riga e i record vengono memorizzati nel buffer finché le righe non vengono eseguite scaricando lo stream.
Flusso API:
CreateWriteStream
AppendRows
⇒FlushRows
(loop)FinalizeWriteStream
(facoltativo)
Selezionare un tipo
Utilizza il seguente diagramma di flusso per decidere quale tipo è più adatto al tuo workload:
Dettagli API
Tieni presente quanto segue quando utilizzi l'API Storage Write:
AppendRows
Il metodo AppendRows
aggiunge uno o più record al flusso. La prima
chiamata a AppendRows
deve contenere un nome di stream insieme allo schema dei dati,
specificato come DescriptorProto
. In alternativa,
puoi aggiungere uno schema Arrow serializzato nella prima chiamata a AppendRows
se
importi i dati nel formato Apache Arrow. Come best practice, invia un batch di
righe in ogni chiamata AppendRows
. Non inviare una riga alla volta.
Gestione del buffer di protocollo
I buffer di protocollo forniscono un meccanismo estensibile, indipendente dal linguaggio e dalla piattaforma per serializzare i dati strutturati in modo compatibile con le versioni precedenti e successive. Sono vantaggiosi in quanto forniscono un'archiviazione compatta dei dati con un'analisi rapida ed efficiente. Per scoprire di più sui protocol buffer, consulta la panoramica dei protocol buffer.
Se intendi utilizzare l'API direttamente con un messaggio protocol buffer predefinito, il messaggio protocol buffer non può utilizzare uno specificatore package
e tutti i tipi di enumerazione o nidificati devono essere definiti all'interno del messaggio radice di primo livello.
Non sono consentiti riferimenti a messaggi esterni. Per un esempio, vedi
sample_data.proto.
I client Java e Go supportano buffer di protocollo arbitrari perché la libreria client normalizza lo schema del buffer di protocollo.
Gestione di Apache Arrow
Per fornire feedback o richiedere assistenza per questa funzionalità, contatta bq-write-api-feedback@google.com.
Apache Arrow è un formato colonnare universale e una cassetta degli attrezzi multilingue per l'elaborazione dei dati. Apache Arrow fornisce un formato di memoria orientato alle colonne indipendente dal linguaggio
per dati piatti e gerarchici, organizzati per operazioni di analisi efficienti
su hardware moderno. Per scoprire di più su Apache Arrow, consulta Apache Arrow.
L'API Storage Write supporta l'importazione di Arrow utilizzando lo schema e i dati Arrow serializzati nella classe AppendRowsRequest
.
La libreria client Python include il supporto integrato per l'importazione di Apache Arrow. Altre lingue potrebbero richiedere la chiamata all'API AppendRows non elaborata per
inserire i dati nel formato Apache Arrow.
FinalizeWriteStream
Il metodo FinalizeWriteStream
finalizza lo stream in modo che non sia possibile
aggiungervi nuovi dati. Questo metodo è obbligatorio nei tipi
Pending
e facoltativo nei tipi
Committed
e
Buffered
. Il flusso predefinito non
supporta questo metodo.
Gestione degli errori
Se si verifica un errore, l'oggetto google.rpc.Status
restituito può includere un
StorageError
nei
dettagli dell'errore. Consulta la
StorageErrorCode
per trovare il tipo di errore specifico. Per
maggiori informazioni sul modello di errore dell'API Google, consulta
Errori.
Connessioni
L'API Storage Write è un'API gRPC che utilizza connessioni
bidirezionali. Il metodo AppendRows
crea una connessione a uno stream. Puoi
aprire più connessioni sullo stream predefinito. Queste aggiunte sono asincrone,
il che ti consente di inviare una serie di scritture contemporaneamente. I messaggi di risposta su ogni connessione bidirezionale arrivano nello stesso ordine in cui sono state inviate le richieste.
Gli stream creati dalle applicazioni 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. Quando utilizzi lo stream predefinito in Java o Go, puoi utilizzare il multiplexing dell'API Storage Write per scrivere in più tabelle di destinazione con connessioni condivise.
In genere, una singola connessione supporta almeno 1 MBps di throughput. Il limite superiore dipende da diversi fattori, come la larghezza di banda della rete, lo schema dei dati e il carico del server. Quando una connessione raggiunge il limite di throughput, le richieste in entrata potrebbero essere rifiutate o messe in coda finché il numero di richieste in corso non diminuisce. Se hai bisogno di una maggiore velocità effettiva, crea più connessioni.
BigQuery chiude la connessione gRPC se 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, creane una nuova. Le librerie client Java e Go si riconnettono automaticamente se la connessione viene chiusa.
Supporto della libreria client
Esistono librerie client per l'API Storage Write in più linguaggi di programmazione ed espongono i costrutti API basati su gRPC sottostanti. Questa API sfrutta funzionalità avanzate come lo streaming bidirezionale, che potrebbe richiedere un lavoro di sviluppo aggiuntivo per il supporto. A questo scopo, per questa API sono disponibili diverse astrazioni di livello superiore che semplificano queste interazioni e riducono i problemi degli sviluppatori. Ti consigliamo di utilizzare queste altre astrazioni della libreria, se possibile.
Questa sezione fornisce ulteriori dettagli su lingue e librerie in cui sono state fornite agli sviluppatori funzionalità aggiuntive oltre all'API generata.
Per visualizzare esempi di codice relativi all'API Storage Write, consulta Tutti gli esempi di codice BigQuery.
Client Java
La libreria client Java fornisce due oggetti writer:
StreamWriter
: accetta i dati nel formato del buffer del protocollo.JsonStreamWriter
: accetta i dati in formato JSON e li converte in buffer del protocollo prima di inviarli via cavo.JsonStreamWriter
supporta anche gli aggiornamenti automatici dello schema. Se lo schema della tabella cambia, lo scrittore si riconnette automaticamente al nuovo schema, consentendo al client di inviare 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 regionale alle richieste e si riconnette dopo gli errori di connessione. Se utilizzi direttamente l'API gRPC, devi gestire questi dettagli.
Client Go
Il client Go utilizza un'architettura client-server per codificare i messaggi nel formato protocol buffer utilizzando proto2. Per informazioni dettagliate su come utilizzare il client Go, con un esempio di codice, consulta la documentazione di Go.
Client Python
Il client Python è un client di livello inferiore che esegue il wrapping dell'API gRPC. Per utilizzare questo client, devi inviare i dati come protocol buffer, seguendo il flusso dell'API per il tipo specificato.
Evita di utilizzare la generazione dinamica di messaggi proto in Python, poiché le prestazioni di questa libreria sono inferiori alla media.
Per scoprire di più sull'utilizzo dei buffer di protocollo con Python, leggi l'esercitazione Nozioni di base sui buffer di protocollo in Python.
Puoi anche utilizzare il formato di importazione Apache Arrow come protocollo alternativo per importare i dati utilizzando l'API Storage Write. Per maggiori informazioni, consulta Utilizzare il formato Apache Arrow per importare i dati.
Client NodeJS
La libreria client NodeJS accetta input JSON e fornisce il supporto per la riconnessione automatica. Per informazioni dettagliate sull'utilizzo del client, consulta la documentazione.
Indisponibilità dell'handle
I nuovi tentativi con backoff esponenziale possono ridurre gli errori casuali e i brevi periodi di mancata disponibilità del servizio, ma per evitare l'eliminazione di righe durante periodi prolungati di mancata disponibilità è necessario un approccio più ponderato. In particolare, se un client non riesce a inserire una riga, cosa deve fare?
La risposta dipende dai tuoi requisiti. Ad esempio, se BigQuery viene utilizzato per l'analisi operativa in cui alcune righe mancanti sono accettabili, il client può rinunciare dopo alcuni tentativi e ignorare i dati. Se, invece, ogni riga è fondamentale per l'attività, ad esempio con i dati finanziari, devi avere una strategia per conservare i dati fino a quando non possono essere inseriti in un secondo momento.
Un modo comune per gestire gli errori persistenti è pubblicare le righe in un argomento Pub/Sub per la valutazione e l'eventuale inserimento successivi. Un altro metodo comune è quello di rendere persistenti temporaneamente i dati sul client. Entrambi i metodi possono mantenere i client sbloccati, garantendo al contempo che tutte le righe possano essere inserite una volta ripristinata la disponibilità.
Esegui lo streaming nelle tabelle partizionate
L'API Storage Write supporta lo streaming di dati in tabelle partizionate.
Quando i dati vengono trasmessi in streaming, vengono inizialmente inseriti nella partizione __UNPARTITIONED__
. Una volta raccolti dati non partizionati sufficienti, BigQuery
ripartiziona i dati, inserendoli nella partizione appropriata.
Tuttavia, non esiste un accordo sul livello del servizio (SLA) che definisca il tempo necessario per spostare i dati dalla partizione __UNPARTITIONED__
.
Per le tabelle partizionate in base all'ora di importazione e partizionate in base alla colonna dell'unità di tempo, i dati non partizionati possono essere esclusi da una query filtrando i valori NULL
dalla partizione __UNPARTITIONED__
utilizzando una delle pseudocolonne (_PARTITIONTIME
o _PARTITIONDATE
a seconda del tipo di dati preferito).
Partizionamento per data di importazione
Quando esegui lo streaming in una tabella partizionata per data di importazione, l'API Storage Write deduce la partizione di destinazione dall'ora UTC corrente del sistema.
Se trasmetti dati in streaming in una tabella partizionata giornalmente, puoi ignorare
l'inferenza della data fornendo un decoratore di partizione come parte della richiesta.
Includi il decoratore nel parametro tableID
. Ad esempio, puoi trasmettere in streaming alla partizione corrispondente al giorno 01/06/2025 per la tabella table1
utilizzando il decoratore di partizione table1$20250601
.
Quando trasmetti in streaming con un decoratore di partizioni, puoi trasmettere in streaming alle partizioni da 31 giorni nel passato a 16 giorni nel futuro. Per scrivere nelle partizioni per le date al di fuori di questi limiti, utilizza un job di caricamento o query, come descritto in Scrivere dati in una partizione specifica.
Lo streaming che utilizza un decoratore di partizioni è supportato solo per le tabelle partizionate giornalmente con flussi predefiniti, non per le tabelle partizionate orarie, mensili o annuali o per i flussi creati dalle applicazioni.
Partizionamento delle colonne di unità di tempo
Quando esegui lo streaming in una tabella partizionata per unità di tempo,
BigQuery inserisce automaticamente i dati nella partizione corretta
in base ai valori della colonna di partizionamento DATE
, DATETIME
o TIMESTAMP
predefinita della tabella. Puoi trasmettere dati in streaming in una tabella partizionata
per unità di tempo se i dati a cui fa riferimento la colonna di partizionamento si trovano tra 10 anni
nel passato e 1 anno nel futuro.
Partizionamento per intervalli di numeri interi
Quando esegui lo streaming in una tabella partizionata per intervallo di numeri interi, BigQuery inserisce automaticamente i dati nella partizione corretta in base ai valori della colonna di partizionamento INTEGER
predefinita della tabella.
Plug-in di output dell'API Storage Write di Fluent Bit
Il plug-in di output dell'API Storage Write di Fluent Bit automatizza il processo di importazione dei record JSON in BigQuery, eliminando la necessità di scrivere codice. Con questo plug-in, devi solo configurare un plug-in di input compatibile e impostare un file di configurazione per iniziare a trasmettere in streaming i dati. Fluent Bit è un processore e un forwarder di log open source e multipiattaforma che utilizza plug-in di input e output per gestire diversi tipi di origini e destinazioni dati.
Questo plug-in supporta quanto segue:
- Semantica at-least-once utilizzando il tipo predefinito.
- Semantica di esecuzione esatta una sola volta utilizzando il tipo di commit.
- Scalabilità dinamica per i flussi predefiniti, quando viene indicata la contropressione.
Metriche del progetto API Storage Write
Per le metriche per monitorare l'importazione dati con l'API Storage Write, utilizza la visualizzazione INFORMATION_SCHEMA.WRITE_API_TIMELINE
o consulta le metricheGoogle Cloud .
Utilizzare DML (Data Manipulation Language) con i dati di streaming recenti
Puoi utilizzare il DML (Data Manipulation Language), ad esempio le istruzioni UPDATE
, DELETE
o
MERGE
, per modificare le righe scritte di recente in una tabella BigQuery
dall'API BigQuery Storage Write. Le scritture recenti sono quelle che si sono verificate
negli ultimi 30 minuti.
Per ulteriori informazioni sull'utilizzo di DML per modificare i dati in streaming, consulta Utilizzo di Data Manipulation Language.
Limitazioni
- Il supporto per l'esecuzione di istruzioni DML mutanti sui dati di streaming recenti non si estende ai dati di streaming utilizzando l'API streaming insertAll.
- L'esecuzione di istruzioni DML mutanti all'interno di una transazione con più istruzioni rispetto ai dati di streaming recenti non è supportata.
Quote dell'API Storage Write
Per informazioni su quote e limiti dell'API Storage Write, consulta la sezione Quote e limiti dell'API BigQuery Storage Write.
Puoi monitorare l'utilizzo della quota di connessioni simultanee e velocità effettiva nella pagina Quote della console.Google Cloud
Calcolare la velocità effettiva
Supponiamo che il tuo obiettivo sia raccogliere log da 100 milioni di endpoint
creando 1500 record di log al minuto. A questo punto, puoi stimare il throughput come
100 million * 1,500 / 60 seconds = 2.5 GB per second
.
Devi assicurarti in anticipo di avere una quota adeguata per gestire questo throughput.
Prezzi dell'API Storage Write
Per i prezzi, consulta Prezzi dell'importazione dati.
Caso d'uso di esempio
Supponiamo che esista una pipeline che elabora i dati sugli eventi dai log degli endpoint. Gli eventi vengono generati continuamente e devono essere disponibili per le query in BigQuery il prima possibile. Poiché la freschezza dei dati è fondamentale per questo caso d'uso, l'API Storage Write è la scelta migliore per importare i dati in BigQuery. Un'architettura consigliata per mantenere questi endpoint snelli consiste nell'inviare eventi a Pub/Sub, da dove vengono utilizzati da una pipeline Dataflow in modalità flusso che trasmette direttamente a BigQuery.
Un problema di affidabilità principale per questa architettura è come gestire l'inserimento di un record in BigQuery non riuscito. Se ogni record è importante e non può essere perso, i dati devono essere memorizzati nel buffer prima di tentare l'inserimento. Nell'architettura consigliata sopra, Pub/Sub può svolgere il ruolo di buffer con le sue funzionalità di conservazione dei messaggi. La pipeline Dataflow deve essere configurata per riprovare gli inserimenti di streaming BigQuery con backoff esponenziale troncato. Una volta esaurita la capacità di Pub/Sub come buffer, ad esempio in caso di mancata disponibilità prolungata di BigQuery o di un errore di rete, i dati devono essere resi persistenti sul client e il client ha bisogno di un meccanismo per riprendere l'inserimento dei record persistenti una volta ripristinata la disponibilità. Per saperne di più su come gestire questa situazione, leggi il post del blog Guida all'affidabilità di Google Pub/Sub.
Un altro caso di errore da gestire è quello di un record dannoso. Un record non valido è un record rifiutato da BigQuery perché l'inserimento non è riuscito con un errore non riproducibile o un record che non è stato inserito correttamente dopo il numero massimo di tentativi. Entrambi i tipi di record devono essere memorizzati in una "coda di messaggi non recapitabili" dalla pipeline Dataflow per ulteriori indagini.
Se è richiesta la semantica di esecuzione esatta, crea un flusso di scrittura di tipo committed, con offset dei record forniti dal client. In questo modo si evitano duplicati, poiché l'operazione di scrittura viene eseguita solo se il valore di offset corrisponde all'offset di accodamento successivo. Se non fornisci un offset, i record vengono aggiunti alla fine corrente dello stream e il tentativo di ripetere un'aggiunta non riuscita potrebbe comportare la visualizzazione del record più di una volta nello stream.
Se non sono necessarie garanzie di esecuzione esatta, la scrittura nel flusso predefinito consente una velocità effettiva maggiore e non viene conteggiata ai fini del limite di quota per la creazione di flussi di scrittura.
Stima il throughput della tua rete e assicurati in anticipo di disporre di una quota adeguata per gestire il throughput.
Se il tuo carico di lavoro genera o elabora dati a una velocità molto irregolare, prova a smussare eventuali picchi di carico sul client e trasmetti in streaming in BigQuery con una velocità effettiva costante. In questo modo puoi semplificare la pianificazione della capacità. Se non è possibile, assicurati di essere pronto a gestire gli errori
429
(risorse esaurite) se e quando la velocità effettiva supera la quota
durante i picchi brevi.
Per un esempio dettagliato di come utilizzare l'API Storage Write, consulta Trasmettere dati in streaming utilizzando l'API Storage Write.
Passaggi successivi
- Trasmettere dati in streaming utilizzando l'API Storage Write
- Caricare i dati in batch utilizzando l'API Storage Write
- Tipi di dati Arrow e buffer di protocollo supportati
- Best practice per l'API Storage Write