Introduzione all'API BigQuery Storage Scrivi

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 usare l'API StorageWrite per inserimento di flussi di record in BigQuery in tempo reale o per elaborare in batch un numero arbitrario di record e li esegue il commit in un'unica operativa.

Vantaggi dell'utilizzo dell'API Storage Scrivi

La semantica della consegna "exactly-once". L'API StorageWrite supporta la semantica "exactly-once" mediante l'uso di offset di flusso. 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 riesce, puoi riprova a eseguire l'operazione.

Transazioni tra stream. Più worker possono creare i propri flussi di 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 StorageWrite è più efficiente il metodo insertAll precedente perché utilizza lo streaming gRPC anziché REST tramite HTTP. L'API StorageWrite supporta anche i formati binari nella 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 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 StorageWrite ha un costo significativamente inferiore rispetto all'API di streaming insertAll precedente. Inoltre, puoi importare fino a 2 TiB al mese gratis.

Autorizzazioni obbligatorie

Per utilizzare l'API StorageWrite, devi avere bigquery.tables.updateData autorizzazioni.

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

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

Per ulteriori informazioni su ruoli e autorizzazioni IAM in per 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 principale dell'API StorageWrite è un flusso. R in modalità flusso scrive i dati in una tabella BigQuery. È possibile eseguire più stream scrivere contemporaneamente nella stessa tabella.

Stream predefinito

L'API StorageWrite fornisce un flusso predefinito, progettato per scenari in cui i dati sono in arrivo in modo continuo. Ha le seguenti caratteristiche:

  • I dati scritti nel flusso predefinito sono immediatamente disponibili per la query.
  • Il flusso predefinito supporta la semantica "at-least-once".
  • Non è necessario creare esplicitamente lo stream predefinito.

Se stai eseguendo la migrazione dalla versione precedente API tabledata.insertall, valuta usando lo stream predefinito. Ha una semantica di scrittura simile, con dati più resilienza e meno restrizioni di scalabilità.

Flusso API:

  1. AppendRows (loop)

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

Flussi creati dall'applicazione

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

  • Scrivere la semantica "exactly-once" mediante l'uso di offset di flusso.
  • 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 un flusso, tutti i dati in attesa diventano disponibili per la lettura. Il commit è un'operazione atomica. Utilizza questo tipo per in modalità batch, in alternativa Job di caricamento BigQuery. Per ulteriori informazioni, vedi Caricare i dati in batch utilizzando l'API Storage Writer.

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 flussi di lavoro dei carichi di lavoro che richiedono una lettura minima una latenza di pochi millisecondi. Il flusso predefinito utilizza una forma "at-least-once" di tipo commit. Per ulteriori informazioni, consulta Utilizzare il tipo di commit per "exactly-once" semantica.

Flusso API:

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

Tipo di buffer

Il tipo con buffer è un tipo avanzato che in genere non dovrebbe essere utilizzato, ad eccezione di Connettore BigQuery I/O di Apache Beam. Se vuoi assicurarti che vengano visualizzati batch di piccole dimensioni, utilizza con un tipo di commit e inviare ogni batch in un'unica richiesta. In questo tipo, a livello di riga, vengono forniti i commit e i record vengono inseriti nel buffer finché non viene eseguito il commit delle righe fare il flush dello stream.

Flusso API:

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

Selezionare un tipo

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

immagine

Dettagli API

Quando utilizzi l'API StorageWrite, considera quanto segue:

AppendRows

Il metodo AppendRows aggiunge uno o più record al flusso. Il primo la chiamata a AppendRows deve contenere il nome di un flusso oltre allo schema dei dati, specificato come DescriptorProto. Come best practice, invia un gruppo di righe in ogni chiamata a AppendRows. Non inviarne una riga alla volta.

Gestione del buffer protocollo

I buffer di protocollo forniscono un'architettura meccanismo di serializzazione di dati strutturati in un ambiente la compatibilità con le versioni precedenti. Sono vantaggiosi in quanto forniscono dati compatti spazio di archiviazione con un'analisi rapida ed efficiente. Per saperne di più sui buffer di protocollo, consulta la Panoramica del buffer di protocollo.

Se utilizzerai l'API direttamente con un buffer di protocollo predefinito , il messaggio del buffer di protocollo non può utilizzare un identificatore 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, vedi 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 il flusso in modo che non possano essere visualizzati nuovi dati aggiunti. Questo metodo è obbligatorio in Pending digita e facoltativo in Committed e Buffered. Lo stream predefinito non supportano questo metodo.

Gestione degli errori

Se si verifica un errore, il valore google.rpc.Status restituito può includere un StorageError nel dettagli dell'errore. Esamina il 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 e altre connessioni. Il metodo AppendRows crea una connessione a uno stream. Puoi e aprire più connessioni nello stream predefinito. Queste aggiunte sono asincrone che ti consente di inviare una serie di scritture contemporaneamente. Risposta i messaggi su ogni connessione bidirezionale arrivano nello stesso ordine sono state inviate.

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 il per il flusso predefinito in Java o Go, puoi utilizzare multiplexing dell'API StorageWrite scrivere in più tabelle di destinazione con connessioni condivise.

In genere, una singola connessione supporta almeno 1 Mbps di velocità effettiva. La parte superiore dipende da diversi fattori, come la larghezza di banda della rete, lo schema e 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 viene completato verso il basso. Se hai bisogno di una velocità effettiva maggiore, 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, creane una nuova. 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, il che potrebbe richiedere ulteriore lavoro di sviluppo. A questo scopo, di astrazioni di livello superiore che semplificano queste interazioni e ridurre le preoccupazioni degli sviluppatori. Consigliamo di sfruttare questi di altre astrazioni di libreria, se possibile.

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

Per vedere gli esempi di codice relativi all'API StorageWrite, vedi qui.

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 aggiornamenti automatici dello schema. Se lo schema della tabella cambia, l'autore 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 è come devi formattare il payload.

L'oggetto writer gestisce una connessione all'API StorageWrite. 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 aggrega l'API gRPC. Per usare questa devi inviare i dati come buffer di protocollo, seguendo il flusso API per del tipo specificato.

Per saperne di più sull'utilizzo dei buffer di protocollo con Python, leggi il Tutorial di base sul buffer del 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 di protocollo supportati per ogni Tipo di dati BigQuery:

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

Il valore è il numero di giorni dall'epoca di Unix (1970/01/01). La l'intervallo valido è compreso tra "-719162" (0001-01-01) e "2932896" (9999-12-31).

DATETIME, TIME string

Il valore deve essere un DATETIME oppure TIME letterale.

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 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 INTERVAL letterale.

RANGE<T> (anteprima) 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 di protocollo, il limite finale di questo intervallo è illimitato.


{
  f_range_date: {
    start: 1
  }
}
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.

Gestire la mancata disponibilità

I nuovi tentativi con backoff esponenziale possono mitigare errori casuali e brevi periodi dell'indisponibilità del servizio, ma per evitare di eliminare righe durante i periodi l'indisponibilità richiede più attenzione. 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, laddove alcune righe mancanti sono accettabili, il client può rinunciare dopo alcuni nuovi tentativi ed eliminare i dati. Se ogni riga è fondamentale per l'attività, ad esempio per i dati finanziari, devi avere una strategia per rendere persistenti 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 successiva e il possibile inserimento. Un altro il metodo più comune consiste nel rendere temporaneamente i dati sul client. Entrambi i metodi possono sbloccare i client e allo stesso tempo garantire che tutte le righe possano inseriti 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 all'interno di __UNPARTITIONED__ della partizione di testo. Dopo aver raccolto un numero sufficiente di dati non partizionati, BigQuery ripartiziona i dati, inserendoli nella partizione appropriata. Tuttavia, non esiste un accordo sul livello del servizio (SLA) che definisca per quanto tempo potrebbe essere necessario per lo spostamento dei dati fuori dalla partizione __UNPARTITIONED__.

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

Metriche dell'API Storage Scrivi

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.

Usare Data Manipulation Language (DML) con flussi di dati recenti

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 negli ultimi 30 minuti.

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

Limitazioni

  • 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 sulle quote e sui limiti dell'API StorageWrite, consulta Quote e limiti dell'API BigQuery Storage write.

Puoi monitorare le connessioni simultanee e l'utilizzo della quota di velocità effettiva nella Pagina Quote di Google Cloud Console.

Calcola la velocità effettiva

Supponiamo che il tuo obiettivo sia raccogliere log da 100 milioni di endpoint con la creazione di un record di 1500 log al minuto. Quindi, puoi stimare la velocità effettiva 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 la sezione 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 l'esecuzione di query in BigQuery il prima possibile. Poiché l'aggiornamento dei dati è fondamentale questo caso d'uso, API Storage Scrivi è la scelta migliore per importare i dati in BigQuery. R architettura consigliata per mantenere questi endpoint, è l'invio di eventi a Pub/Sub, dove vengono utilizzate da una pipeline Dataflow in modalità flusso che invia flussi di dati direttamente a BigQuery.

Uno dei principali problemi di affidabilità di questa architettura è come gestire gli errori per inserire 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. Dataflow la pipeline deve essere configurata per riprovare a inserire i flussi di dati BigQuery con backoff esponenziale troncato. Dopo la capacità di Pub/Sub quando il buffer è esaurito, ad esempio, in caso di prolungata indisponibilità di BigQuery o in caso di errore di rete, i dati devono essere resi persistenti Il client necessita di un meccanismo per riprendere l'inserimento dei record persistenti 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 dei record di veleno. La documentazione di un veleno è o un record rifiutato da BigQuery perché non riesce a inserire con un errore non ripetibile o un record che non è stato eseguito correttamente inserito dopo il numero massimo di nuovi tentativi. Entrambi i tipi di record devono essere archiviati in un "coda messaggi non recapitabili" da parte della pipeline Dataflow per ulteriori indagini.

Se è richiesta la semantica "exactly-once", crea un flusso di scrittura in di tipo impegnato, con compensazioni record fornite dal cliente. 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.

Stimare la velocità effettiva della rete e assicurarti in anticipo di disporre di una quota adeguata per gestire la velocità effettiva.

Se il carico di lavoro genera o elabora dati a una velocità molto non uniforme, cercare di attenuare eventuali picchi di carico sul client e trasmettere in streaming BigQuery con una velocità effettiva costante. Questo può semplificare e 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