Introduzione all'API BigQuery Storage Write

L'API BigQuery StorageWrite è un'API di importazione dati unificata per in BigQuery. Combina l'importazione di flussi di dati e il caricamento in batch un'unica API ad alte prestazioni. Puoi utilizzare l'API Storage Write per caricare i record in BigQuery in tempo reale o per elaborare in batch un numero arbitrariamente elevato di record e sottoporli a commit in un'unica operazione atomica.

Vantaggi dell'utilizzo dell'API Storage Scrivi

Semantica di consegna "exactly-once". L'API Storage Write supporta la semantica "exactly-once" tramite l'utilizzo degli offset dello stream. A differenza del tabledata.insertAll, l'API StorageWrite non scrive mai due messaggi che hanno lo stesso offset all'interno di un flusso, se il client fornisce durante l'aggiunta di record.

Transazioni a livello di stream. Puoi scrivere i dati in un flusso ed eseguire il commit come una singola transazione. Se l'operazione di commit non va a buon fine, puoi riprova a eseguire l'operazione.

Transazioni tra stream. Più worker possono creare i propri flussi di elaborare i dati in modo indipendente. Al termine del lavoro di tutti i worker, puoi committare tutti gli stream come transazione.

Protocollo efficiente. L'API StorageWrite è più efficiente il metodo insertAll precedente 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 trasmissione più efficiente del JSON. Le richieste di scrittura sono asincrone con l'ordine garantito.

Rilevamento degli aggiornamenti dello schema. Se lo schema della tabella sottostante cambia mentre mentre un client sta trasmettendo in streaming, l'API StorageWrite invia una notifica al client. Il client può decidere se riconnettersi utilizzando lo schema aggiornato o continuare in scrittura sulla connessione esistente.

Riduzione dei costi. L'API Storage Write ha un costo notevolmente inferiore rispetto all'API di inserimento di flussi insertAll precedente. Inoltre, puoi importare fino a 2 TiB al mese gratis.

Autorizzazioni obbligatorie

Per utilizzare l'API Storage Write, devi disporre delle autorizzazionibigquery.tables.updateData.

I seguenti ruoli predefiniti di Identity and Access Management (IAM) includono bigquery.tables.updateData autorizzazioni:

  • bigquery.dataEditor
  • bigquery.dataOwner
  • bigquery.admin

Per ulteriori informazioni sui ruoli e sulle autorizzazioni IAM in BigQuery, consulta Ruoli e autorizzazioni predefiniti.

Ambiti di autenticazione

L'utilizzo dell'API StorageWrite 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 StorageWrite

L'astrazione di base nell'API Storage Write è uno stream. R in modalità flusso scrive i dati in una tabella BigQuery. Più stream possono 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 la query.
  • Lo stream predefinito supporta la semantica almeno una volta.
  • Non è necessario creare esplicitamente lo stream predefinito.

Se esegui la migrazione dall'API tabledata.insertall precedente, ti consigliamo di utilizzare lo stream predefinito. Ha una semantica di scrittura simile, con dati più resilienza e meno restrizioni di scalabilità.

Flusso dell'API:

  1. AppendRows (loop)

Per ulteriori informazioni ed esempi di codice, consulta Utilizza il flusso predefinito per la semantica "at-least-once".

Stream creati dall'applicazione

Puoi creare esplicitamente uno stream se hai bisogno di una delle seguenti opzioni comportamenti:

  • Semantika di scrittura esattamente una volta tramite l'utilizzo di offset dello stream.
  • Supporto di altre proprietà ACID.

In generale, i flussi creati dall'applicazione offrono un maggiore controllo sulle funzionalità in il costo della complessità aggiuntiva.

Quando crei uno stream, devi specificare un tipo. Il tipo controlla quando i dati scritta nel flusso diventa visibile in BigQuery per la lettura.

Tipo in attesa

Nel tipo In attesa, i record rimangono memorizzati nel buffer nello stato In attesa fino a quando non esegui il commit. durante lo streaming. 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 carichi di lavoro batch, come alternativa ai job di caricamento BigQuery. Per ulteriori informazioni, vedi Caricare i dati in batch utilizzando l'API StorageWrite.

Flusso API:

  1. CreateWriteStream
  2. AppendRows (loop)
  3. FinalizeWriteStream
  4. BatchCommitWriteStreams

Tipo di impegno

Con il tipo impegnato, i record sono disponibili per la lettura immediatamente durante la scrittura direttamente al live streaming. Utilizza questo tipo per i carichi di lavoro in streaming che richiedono una latenza di lettura minima. Lo stream predefinito utilizza una forma almeno una volta del tipo di commit. Per ulteriori informazioni, consulta Utilizzare il tipo di commit per la semantica esattamente una volta.

Flusso API:

  1. CreateWriteStream
  2. AppendRows (loop)
  3. FinalizeWriteStream (facoltativo)

Tipo con buffer

Il tipo con buffer è un tipo avanzato che in genere non deve essere utilizzato, tranne con il connettore Apache Beam BigQuery I/O. Se hai piccoli batch che vuoi garantire che vengano visualizzati insieme, utilizza il tipo impegnato e invia ogni batch in una richiesta. In questo tipo, vengono forniti commit a livello di riga e i record vengono memorizzati in un buffer fino al commit delle righe tramite svuotamento dello stream.

Flusso API:

  1. CreateWriteStream
  2. AppendRowsFlushRows (loop)
  3. FinalizeWriteStream (facoltativo)

Selezione di un tipo

Utilizza il seguente diagramma di flusso per decidere qual è il tipo più adatto alle tue esigenze carico di lavoro:

immagine

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 stream insieme allo schema dei dati, specificato come DescriptorProto. Come best practice, invia un gruppo di righe in ogni chiamata a AppendRows. Non inviare una riga alla volta.

Gestione del buffer di proto

I buffer di protocollo forniscono un'architettura meccanismo di serializzazione di dati strutturati in un ambiente compatibile con le versioni precedenti. Sono vantaggiosi in quanto forniscono uno spazio di archiviazione dei dati compatto con analisi rapida ed efficiente. Per scoprire di più sui buffer di protocollo, consulta la Panoramica dei buffer di protocollo.

Se intendi utilizzare l'API direttamente con un messaggio predefinito del buffer di protocollo, il messaggio del buffer di protocollo non può utilizzare un specificatore package e tutti i tipi di enumerazione o nidificati devono essere definiti all'interno del messaggio principale di primo livello. Non sono consentiti riferimenti a messaggi esterni. Per un esempio, consulta sample_data.proto.

I client Java e Go supportano buffer di protocollo arbitrari perché il client che normalizza lo schema di buffer di protocollo.

FinalizeWriteStream

Il metodo FinalizeWriteStream finalizza lo stream in modo che non sia possibile aggiungere nuovi dati. Questo metodo è obbligatorio in Pending digita e facoltativo in Committed e Buffered. Lo stream predefinito non supporta questo metodo.

Gestione degli errori

Se si verifica un errore, l'oggetto google.rpc.Status restituito può includere un valore StorageError nei dettagli dell'errore. Esamina StorageErrorCode per trovare il tipo di errore specifico. Per ulteriori informazioni sul modello di errore delle API di Google, consulta Errori.

Connessioni

L'API StorageWrite è un'API gRPC che utilizza i e connessioni a Internet. Il metodo AppendRows crea una connessione a uno stream. Puoi aprire più connessioni nello stream predefinito. Questi aggiunte sono asincrone, il che ti consente di inviare contemporaneamente una serie di scritture. I messaggi di risposta su ogni connessione bidirezionale arrivano nello stesso ordine in cui sono state inviate le richieste.

I flussi creati dall'applicazione possono avere un solo attivo connessione. Come best practice, limitare il numero di connessioni attive, e utilizzare un'unica 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 velocità effettiva. Il valore 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 velocità effettiva, le richieste potrebbero essere rifiutate o messe in coda finché il numero di richieste in corso non va verso il basso. Se hai bisogno di una maggiore velocità in uscita, crea più connessioni.

BigQuery chiude la connessione gRPC se la connessione rimane inattivo per troppo tempo. In questo caso, il codice di risposta è HTTP 409. gRPC, connessione può essere chiusa anche in caso di riavvio del server o per altre motivi. Se si verifica un errore di connessione, crea una nuova connessione. Java e Go Le librerie client si riconnettono automaticamente quando la connessione viene chiusa.

Supporto della libreria client

Esistono librerie client per l'API StorageWrite in più linguaggi di programmazione ed espongono l'API sottostante basata su gRPC costrutti. Questa API sfrutta funzionalità avanzate come lo streaming bidirezionale, che potrebbe richiedere un ulteriore lavoro di sviluppo per il supporto. A tal fine, per questa API sono disponibili una serie di astrazioni di livello superiore che semplificano queste interazioni e riducono i problemi degli sviluppatori. Consigliamo di sfruttare questi di altre astrazioni di libreria, se possibile.

Questa sezione fornisce ulteriori dettagli sui linguaggi e sulle librerie in cui sono state fornite agli sviluppatori funzionalità aggiuntive rispetto all'API generata.

Per visualizzare esempi di codice relativi all'API Storage Write, visita questa pagina.

Client Java

La libreria client Java fornisce due oggetti writer:

  • StreamWriter: accetta i dati nel formato del buffer di protocollo.

  • JsonStreamWriter: accetta i dati in formato JSON e li converte in protocollo buffer prima di inviarlo tramite il cavo. JsonStreamWriter supporta anche gli aggiornamenti automatici dello schema. Se lo schema della tabella cambia, lo scrittore si ricollega 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'autore pulisce automaticamente le richieste, aggiunge le intestazioni di routing a livello di regione richieste e si riconnette dopo un errore di connessione. Se usi l'API gRPC devi gestire direttamente questi dettagli.

Client Go

Il client Go utilizza un'architettura client-server per codificare i messaggi all'interno di formato di buffer di protocollo utilizzando proto2. Consulta la documentazione di Go per dettagli su come utilizzare il client Go, con un codice di esempio.

Client Python

Il client Python è un client di livello inferiore che avvolge l'API gRPC. Per utilizzare questo client, devi inviare i dati come buffer di protocollo, seguendo il flusso dell'API per il tipo specificato.

Per scoprire di più sull'utilizzo dei buffer di protocollo con Python, leggi il tutorial sulle nozioni di base sui buffer di protocollo in Python.

Client NodeJS

Il client NodeJS lib accetta input JSON e fornisce la riconnessione automatica assistenza in tempo reale. Consulta la documentazione per informazioni dettagliate su come utilizzare il client.

Conversioni dei tipi di dati

La tabella seguente mostra i tipi di buffer del protocollo supportati per ogni tipo di dati BigQuery:

Tipo di dati BigQuery Tipi di buffer di protocollo supportati
BOOL bool, int32, int64, uint32, uint64, google.protobuf.BoolValue
BYTES bytes, string, google.protobuf.BytesValue
DATE int32 (opzione preferita), int64, string

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

Il valore deve essere un valore letterale DATETIME o TIME.

int64

Utilizza la CivilTimeEncoder per eseguire la conversione.

FLOAT double, float, google.protobuf.DoubleValue, google.protobuf.FloatValue
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 string
bytes, google.protobuf.BytesValue

Utilizza la classe BigDecimalByteStringEncoder per eseguire la conversione.

STRING string, enum, google.protobuf.StringValue
TIME string

Il valore deve essere un TIME letterale.

TIMESTAMP int64 (opzione preferita), int32, uint32 google.protobuf.Timestamp

Il valore è espresso in microsecondi dall'epoca di Unix (1970-01-01).

INTERVAL string, google.protobuf.Duration

Il valore della stringa deve essere un letterale INTERVAL.

RANGE<T> message

Un tipo di messaggio nidificato nel protocollo con due campi, start e end, in cui entrambi i campi devono avere lo stesso tipo di buffer di protocollo supportato che corrisponde a un tipo di dati BigQuery T. T deve essere DATE, DATETIME o TIMESTAMP. Se un campo (start o end) non è impostato nel messaggio di protocollo, rappresenta un confine illimitato. Nell'esempio seguente, f_range_date rappresenta una colonna RANGE in una tabella. Poiché il campo end non è impostato nel messaggio proto, il confine di fine di questo intervallo non è limitato.


{
  f_range_date: {
    start: 1
  }
}
REPEATED FIELD array

Un tipo di array nel proto corrisponde a un campo ripetuto in BigQuery.

RECORD message

Un tipo di messaggio nidificato nel protocollo corrisponde a un campo di record in BigQuery.

Gestire la mancata disponibilità

La ripetizione dei tentativi con backoff esponenziale può attenuare gli errori casuali e brevi periodi di mancata disponibilità del servizio, ma per evitare di eliminare righe durante periodi di mancata disponibilità prolungati è necessario un approccio più ponderato. In particolare, se un client continua a utilizzare 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 per i dati finanziari, devi avere una strategia per mantenere 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 futuri. Un altro metodo comune è la persistenza temporanea dei dati sul client. Entrambi i metodi possono mantenere i client sbloccati e, al contempo, garantire che tutte le righe possano essere inserite una volta ripristinata la disponibilità.

Partizionamento delle colonne in base all'unità di tempo

Puoi inserire flussi di dati in una tabella partizionata in base a DATE, DATETIME o TIMESTAMP con un periodo compreso tra 5 anni nel passato e 1 anno nel futuro. I dati che non rientrano in questo intervallo sono stati rifiutati.

Quando i dati vengono trasmessi in flusso, vengono inizialmente posizionati nella sezione __UNPARTITIONED__ della partizione di testo. Dopo aver raccolto dati non partizionati sufficienti, BigQuery li ripartisce nella partizione appropriata. Tuttavia, non esiste un accordo sul livello del servizio (SLA) che definisce il tempo necessario per il trasferimento dei dati dalla partizione __UNPARTITIONED__.

L'API StorageWrite non supporta l'uso di decoratori della partizione.

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, è sufficiente per configurare un plug-in di input compatibile e impostare un file di configurazione per iniziare dei flussi di dati. Fluent Bit è un metodo open source e processore di log e inoltro di log multipiattaforma che utilizza plug-in di input e output per gestire diversi tipi di origini dati e sink.

Questo plug-in supporta quanto segue:

  • semantica "at-least-once" con il tipo predefinito.
  • Semantika esattamente una volta utilizzando il tipo di commit.
  • Scalabilità dinamica per flussi predefiniti, quando è indicata una contropressione.

Metriche dell'API Storage Write

Affinché le metriche possano monitorare l'importazione dati con l'API StorageWrite, come la latenza a livello di richiesta lato server, per connessioni simultanee, byte caricati e righe caricate, Metriche Google Cloud.

Utilizzare il linguaggio di manipolazione dei dati (DML) con i dati sottoposti a streaming di recente

Puoi usare il Data Manipulation Language (DML), ad esempio UPDATE, DELETE, Istruzioni MERGE, per modificare le righe scritte di recente in una risorsa BigQuery dall'API BigQuery StorageWrite. Le scritture recenti sono quelle che si sono verificate gli ultimi 30 minuti.

Per ulteriori informazioni sull'utilizzo di DML per modificare i flussi di dati, consulta Utilizzare il Data Manipulation Language (DDL).

Limitazioni

  • Supporto per l'esecuzione di istruzioni DML mutanti su dati trasmessi di recente non si estende ai flussi di dati trasmessi utilizzando l'API BigQuery Storage Scrivi tipo con buffer
  • Supporto per l'esecuzione di istruzioni DML mutanti su dati trasmessi di recente non si estende ai dati trasmessi in flussi utilizzando l'API insertAll streaming.
  • Esecuzione di istruzioni DML mutanti all'interno di una transazione con più istruzioni rispetto ai flussi di dati recenti non sono supportati.

Quote dell'API Storage Scrivi

Per informazioni su quote e limiti dell'API Storage Write, consulta Quote e limiti dell'API BigQuery Storage Write.

Puoi monitorare l'utilizzo delle quote relative a connessioni simultanee e throughput nella pagina Quote della console Google Cloud.

Calcolare la velocità effettiva

Supponiamo che il tuo obiettivo sia raccogliere i log da 100 milioni di endpoint creando 1500 record di log al minuto. Poi puoi stimare il throughput come 100 million * 1,500 / 60 seconds = 2.5 GB per second. Devi assicurarti in anticipo di disporre di una quota adeguata per gestire questa velocità effettiva.

Prezzi dell'API Storage Scrivi

Per i prezzi, consulta Prezzi dell'importazione dati.

Caso d'uso di esempio

Supponiamo che esista una pipeline che elabora i dati degli eventi dai log degli endpoint. Gli eventi vengono generati continuamente e devono essere disponibili per le query in BigQuery il prima possibile. Poiché l'aggiornamento 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 essenziali è l'invio di eventi a Pub/Sub, da dove vengono utilizzati da una pipeline Dataflow in modalità flusso che trasmette direttamente in BigQuery.

Un problema di affidabilità principale per questa architettura è come gestire l'errore di inserimento di un record in BigQuery. Se ogni record è importante non possono andare persi, i dati devono essere inseriti nel buffer prima di tentare di inserirli. Nella all'architettura consigliata di cui sopra, Pub/Sub può svolgere il ruolo buffer con le sue funzionalità di conservazione dei messaggi. La pipeline Dataflow deve essere configurata per riprovare gli inserimenti in streaming di BigQuery con backoff esponenziale troncato. Una volta esaurita la capacità di Pub/Sub come buffer, ad esempio in caso di indisponibilità prolungata di BigQuery o di un errore di rete, i dati devono essere mantenuti nel client e il client deve disporre di un meccanismo per riprendere l'inserimento dei record permanenti una volta ripristinata la disponibilità. Per ulteriori informazioni su come gestire vedi la situazione Guida all'affidabilità di Google Pub/Sub post del blog.

Un altro caso di errore da gestire è quello di un record dannoso. Un record dannoso è un record rifiutato da BigQuery perché non è stato inserito con un errore non ripetibile o un record che non è stato inserito correttamente dopo il numero massimo di tentativi. Entrambi i tipi di record devono essere archiviati in un "coda messaggi non recapitabili" da parte della pipeline Dataflow per ulteriori indagini.

Se sono necessarie la semantica esatta una volta e la funzionalità di commit, crea uno stream di scrittura in tipo di commit con gli offset dei record forniti dal client. In questo modo vengono evitati i duplicati, mentre viene eseguita solo se il valore di offset corrisponde all'offset dell'aggiunta successiva. Se non specifichi un offset, i record vengono aggiunti alla fine corrente della un flusso di dati e un nuovo tentativo di aggiunta non riuscita potrebbe far sì che il record venga visualizzato più di una volta nello stream.

Se non sono necessarie garanzie "exactly-once", nello stream predefinito consente una velocità effettiva più elevata e non viene inoltre conteggiata nei limite di quota sulla 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 frequenza molto irregolare, prova a smussare gli eventuali picchi di carico sul client e a trasmettere in streaming in BigQuery con un throughput costante. Questo può semplificare la pianificazione della capacità. Se ciò non è possibile, assicurati di poter gestire Errori di 429 (risorsa esaurita) se e quando la velocità effettiva supera la quota durante brevi picchi.

Passaggi successivi