Best practice per l'API BigQuery Storage Write
Questo documento fornisce le best practice per l'utilizzo dell'API BigQuery Storage Write. Prima di leggere questo documento, leggi Panoramica dell'API BigQuery Storage Write.
Limitare la velocità di creazione degli stream
Prima di creare un flusso, valuta se puoi utilizzare il flusso predefinito. Per gli scenari di streaming, lo stream predefinito ha meno limitazioni di quota e può essere scalato meglio rispetto all'utilizzo di stream creati dall'applicazione. Se utilizzi un flusso creato dall'applicazione, assicurati di utilizzare il throughput massimo su ogni flusso prima di creare flussi aggiuntivi. Ad esempio, utilizza scritture asincrone.
Per gli stream creati dalle applicazioni, evita di chiamare CreateWriteStream
con una frequenza elevata. In genere, se superi le 40-50 chiamate al secondo, la latenza delle
chiamate API aumenta notevolmente (> 25 secondi). Assicurati che la tua applicazione possa accettare un
avvio a freddo e aumenti gradualmente il numero di stream e limiti la frequenza di
chiamate CreateWriteStream
. Puoi anche impostare una scadenza più lunga per attendere il completamento della
chiamata, in modo che non si verifichi un errore DeadlineExceeded
. Esiste
anche una quota a lungo termine sulla velocità
massima di CreateWriteStream
chiamate. La creazione di stream è un processo che richiede molte risorse, quindi ridurre la velocità di creazione degli stream e utilizzare appieno quelli esistenti è il modo migliore per non superare questo limite.
Gestione del pool di connessioni
Il metodo AppendRows
crea una connessione bidirezionale a uno stream. Puoi
aprire più connessioni sullo stream predefinito, ma solo una connessione
attiva sugli stream creati dall'applicazione.
Quando utilizzi il flusso predefinito, puoi utilizzare il multiplexing dell'API Storage Write per scrivere in più tabelle di destinazione con connessioni condivise. Multiplexing delle connessioni dei pool per una migliore velocità effettiva e utilizzo delle risorse. Se il tuo flusso di lavoro ha più di 20 connessioni simultanee, ti consigliamo di utilizzare il multiplexing. Il multiplexing è disponibile in Java e Go. Per i dettagli di implementazione di Java, consulta Utilizzare il multiplexing. Per i dettagli dell'implementazione di Go, vedi Condivisione della connessione (multiplexing). Se utilizzi il connettore Beam con semantica at-least-once, puoi attivare il multiplexing tramite UseStorageApiConnectionPool. Il connettore Dataproc Spark ha il multiplexing attivato per impostazione predefinita.
Per ottenere le prestazioni migliori, utilizza una connessione per il maggior numero possibile di scritture di dati. Non utilizzare una connessione per una sola scrittura o aprire e chiudere stream per molte piccole scritture.
Esiste una quota per il numero di
connessioni simultanee che possono essere
aperte contemporaneamente per progetto. Al di sopra del limite, le chiamate a AppendRows
non vanno a buon fine.
Tuttavia, la quota per le connessioni simultanee può essere aumentata e normalmente non dovrebbe
essere un fattore limitante per lo scaling.
Ogni chiamata a AppendRows
crea un nuovo oggetto writer di dati. Pertanto,
quando utilizzi un flusso creato dall'applicazione, il numero di connessioni corrisponde
al numero di flussi creati. 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, ma può superare i 10 MBps.
Esiste anche una quota per il throughput totale per progetto. Questo valore rappresenta i byte al secondo in tutte le connessioni che passano attraverso il servizio API Storage Write. Se il tuo progetto supera questa quota, puoi richiedere un aggiustamento della quota. In genere, ciò comporta l'aumento delle quote associate, come la quota di connessioni simultanee, in un rapporto uguale.
Gestire gli offset dello stream per ottenere la semantica exactly-once
L'API Storage Write consente solo di scrivere alla fine corrente dello stream, che si sposta man mano che vengono aggiunti dati. La posizione corrente nel flusso viene specificata come offset dall'inizio del flusso.
Quando scrivi in un flusso creato dall'applicazione, puoi specificare l'offset del flusso per ottenere una semantica di scrittura esattamente una volta.
Quando specifichi un offset, l'operazione di scrittura è idempotente, il che rende sicuro riprovare a causa di errori di rete o mancata risposta del server. Gestisci i seguenti errori relativi agli offset:
ALREADY_EXISTS
(StorageErrorCode.OFFSET_ALREADY_EXISTS
): la riga era già stata scritta. Puoi ignorare questo errore.OUT_OF_RANGE
(StorageErrorCode.OFFSET_OUT_OF_RANGE
): un'operazione di scrittura precedente non è riuscita. Riprova dall'ultima scrittura riuscita.
Tieni presente che questi errori possono verificarsi anche se imposti il valore di offset errato, quindi devi gestire gli offset con attenzione.
Prima di utilizzare gli offset di flusso, valuta se hai bisogno di una semantica di tipo exactly-once. Ad esempio, se la pipeline di dati upstream garantisce solo scritture at-least-once o se puoi rilevare facilmente i duplicati dopo l'importazione dati, potresti non aver bisogno di scritture exactly-once. In questo caso, ti consigliamo di utilizzare lo stream predefinito, che non richiede di tenere traccia degli offset di riga.
Non bloccare le chiamate su AppendRows
Il metodo AppendRows
è asincrono. Puoi inviare una serie di scritture senza
bloccare una risposta per ogni scrittura singolarmente. I messaggi di risposta sulla
connessione bidirezionale arrivano nello stesso ordine in cui sono state accodate le richieste.
Per ottenere la massima velocità effettiva, chiama AppendRows
senza bloccare l'attesa della
risposta.
Gestire gli aggiornamenti dello schema
Per gli scenari di streaming dei dati, gli schemi delle tabelle vengono in genere gestiti al di fuori della pipeline di streaming. È normale che lo schema si evolva nel tempo, ad esempio aggiungendo nuovi campi che accettano valori null. Una pipeline solida deve gestire gli aggiornamenti dello schema fuori banda.
L'API Storage Write supporta gli schemi delle tabelle nel seguente modo:
- La prima richiesta di scrittura include lo schema.
- Ogni riga di dati viene inviata come buffer di protocollo binario. BigQuery mappa i dati allo schema.
- Puoi omettere i campi nullabili, ma non puoi includere campi non presenti nello schema attuale. Se invii righe con campi aggiuntivi, l'API Storage Write restituisce un
StorageError
conStorageErrorCode.SCHEMA_MISMATCH_EXTRA_FIELD
.
Se vuoi inviare nuovi campi nel payload, devi prima aggiornare lo schema della tabella in BigQuery. L'API Storage Write rileva
le modifiche allo schema dopo un breve periodo di tempo, nell'ordine di minuti. Quando l'API Storage Write rileva la modifica dello schema, il messaggio di risposta AppendRowsResponse
contiene un oggetto TableSchema
che descrive il nuovo schema.
Per inviare dati utilizzando lo schema aggiornato, devi chiudere le connessioni esistenti e aprire nuove connessioni con il nuovo schema.
Client Java. La libreria client Java fornisce alcune funzionalità aggiuntive per
gli aggiornamenti dello schema tramite la classe JsonStreamWriter
. Dopo
un aggiornamento dello schema, JsonStreamWriter
si riconnette automaticamente allo schema aggiornato. Non è necessario chiudere e riaprire esplicitamente la connessione.
Per verificare le modifiche allo schema a livello di programmazione, chiama
AppendRowsResponse.hasUpdatedSchema
dopo il completamento del metodo append
.
Puoi anche configurare JsonStreamWriter
per ignorare i campi sconosciuti nei
dati di input. Per impostare questo comportamento, chiama
setIgnoreUnknownFields
. Questo comportamento è simile
all'opzione ignoreUnknownValues
quando si utilizza l'API
tabledata.insertAll
legacy. Tuttavia, può causare la perdita involontaria di dati, perché i campi sconosciuti vengono
eliminati automaticamente.