Best practice per l'API BigQuery Storage di scrittura
Questo documento fornisce le best practice per l'utilizzo dell'API BigQuery Storage di scrittura. Prima di leggere questo documento, consulta la Panoramica dell'API BigQuery Storage di scrittura.
Limitare la frequenza di creazione degli stream
Prima di creare uno stream, valuta se puoi utilizzare lo stream predefinito. Per gli scenari di streaming, lo stream predefinito ha meno limitazioni di quota e può scalare meglio rispetto all'utilizzo di stream creati dall'applicazione. Se utilizzi uno stream creato dall'applicazione, assicurati di utilizzare il throughput massimo su ogni stream prima di creare stream aggiuntivi. Ad esempio, utilizza le scritture asincrone.
Per gli stream creati dall'applicazione, evita di chiamare CreateWriteStream con una frequenza elevata. In genere, se superi le 40-50 chiamate al secondo, la latenza delle chiamate API aumenta in modo significativo (>25 secondi). Assicurati che la tua applicazione possa accettare un avvio a freddo e aumentare gradualmente il numero di stream e limitare la frequenza delle chiamate CreateWriteStream. Puoi anche impostare una scadenza più lunga per attendere il completamento della chiamata, in modo che non generi un errore DeadlineExceeded. Esiste
anche una quota a lungo termine quota sulla frequenza massima
delle chiamate CreateWriteStream. La creazione di stream è un processo che richiede molte risorse, quindi il modo migliore per non superare questo limite è ridurre la frequenza di creazione degli stream e utilizzare completamente gli stream esistenti.
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 singola connessione attiva sugli stream creati dall'applicazione.
Quando utilizzi lo stream predefinito, puoi utilizzare il multiplexing dell'API Storage Write per scrivere in più tabelle di destinazione con connessioni condivise. Il multiplexing raggruppa le connessioni per migliorare il throughput e l'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 sull'implementazione Java, consulta Utilizzare il multiplexing. Per i dettagli sull'implementazione di Go, consulta Condivisione delle connessioni (multiplexing). Se utilizzi il connettore Beam con semantica at-least-once, puoi abilitare il multiplexing tramite UseStorageApiConnectionPool. Il connettore Dataproc Spark ha il multiplexing abilitato per impostazione predefinita.
Per ottenere prestazioni ottimali, 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 sul numero di
connessioni simultanee che possono essere
aperte contemporaneamente per progetto. Se superi il limite, le chiamate a AppendRows non vanno a buon fine.
Tuttavia, la quota per le connessioni simultanee può essere aumentata e in genere non dovrebbe essere un fattore limitante per la scalabilità.
Ogni chiamata a AppendRows crea un nuovo oggetto writer di dati. Pertanto, quando utilizzi uno stream creato dall'applicazione, il numero di connessioni corrisponde al numero di stream creati. In genere, una singola connessione supporta un throughput di almeno 1 MBps. 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 sul throughput totale per progetto. Rappresenta i byte al secondo su tutte le connessioni che passano attraverso il servizio API Storage Write. Se il tuo progetto supera questa quota, puoi richiedere una modifica della quota. In genere, ciò comporta l'aumento delle quote associate, come la quota delle connessioni simultanee, in un rapporto uguale.
Gestire gli offset degli stream per ottenere la semantica exactly-once
L'API Storage Write consente solo le scritture alla fine corrente dello stream, che si sposta man mano che i dati vengono aggiunti. La posizione corrente nello stream viene specificata come offset dall'inizio dello stream.
Quando scrivi in uno stream creato dall'applicazione, puoi specificare l'offset dello stream per ottenere la semantica di scrittura exactly-once.
Quando specifichi un offset, l'operazione di scrittura è idempotente, il che la rende sicura per i nuovi tentativi 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 è già stata scritta. Puoi ignorare questo errore in sicurezza.OUT_OF_RANGE(StorageErrorCode.OFFSET_OUT_OF_RANGE): un'operazione di scrittura precedente non è andata a buon fine. 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 degli stream, valuta se hai bisogno della semantica exactly-once. Ad esempio, se la pipeline di dati upstream garantisce solo scritture at-least-once o se puoi rilevare facilmente i duplicati dopo 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 delle righe.
Non bloccare le chiamate 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 le richieste sono state accodate.
Per ottenere il throughput più elevato, chiama AppendRows senza bloccare l'attesa della risposta.
Gestire gli aggiornamenti dello schema
Per gli scenari di streaming di 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 nullabili. Una pipeline robusta deve gestire gli aggiornamenti dello schema out-of-band.
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 corrente. Se invii righe con campi aggiuntivi, l'
API Storage Write restituisce un
StorageErrorconStorageErrorCode.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 dello 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 i dati utilizzando lo schema aggiornato, devi chiudere le connessioni esistenti e aprirne di nuove con il nuovo schema.
Client Java. La libreria client Java fornisce alcune funzionalità aggiuntive per
gli aggiornamenti dello schema, tramite la JsonStreamWriter classe. Dopo un aggiornamento dello schema, JsonStreamWriter si riconnette automaticamente con lo schema aggiornato. Non è necessario chiudere e riaprire esplicitamente la connessione.
Per verificare a livello di programmazione le modifiche dello schema, chiama
AppendRowsResponse.hasUpdatedSchema al termine del append
metodo.
Puoi anche configurare JsonStreamWriter in modo che ignori i campi sconosciuti nei dati di input. Per impostare questo comportamento, chiama
setIgnoreUnknownFields. Questo comportamento è simile a
l'opzione ignoreUnknownValues quando si utilizza l'API legacy
tabledata.insertAll. Tuttavia, può causare una perdita di dati involontaria, perché i campi sconosciuti vengono eliminati senza preavviso.