Best practice per l'API BigQuery Storage Scrivi
Questo documento fornisce le best practice per l'utilizzo dell'API BigQuery StorageWrite. Prima di leggere questo documento, consulta la Panoramica dell'API BigQuery Storage Write.
Limitare la frequenza di creazione dello stream
Prima di creare uno stream, valuta se puoi utilizzare streaming predefinito. Per streaming scenari predefiniti, il flusso predefinito ha meno limiti di quota e può scalare meglio rispetto all'utilizzo di flussi creati dall'applicazione. Se utilizzi un'applicazione creata assicurati di utilizzare la velocità effettiva massima su ciascun flusso prima creando flussi di dati aggiuntivi. Ad esempio, utilizza scritture asincrone.
Per gli stream creati dall'applicazione, evita di chiamare CreateWriteStream
con frequenza elevata. In genere, se superi 40-50 chiamate al secondo, la latenza delle chiamate API aumenta notevolmente (>25 s). Assicurati che la tua richiesta possa accettare un
avviare a freddo e aumentare gradualmente il numero di flussi e limitare la frequenza
CreateWriteStream
chiamate. Puoi anche impostare una scadenza più ampia per attendere
per il completamento, in modo che l'operazione non venga interrotta con un errore DeadlineExceeded
. Là
rappresenta anche una quota a lungo termine
percentuale di chiamate CreateWriteStream
. La creazione di flussi di dati richiede molte risorse
di processo, riducendo così la frequenza di creazione di stream e sfruttando appieno le risorse 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
apri più connessioni sullo stream predefinito, ma solo una singola
di connessione sui flussi 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 in Java, consulta Utilizzare il multiplexing. Per Go dettagli di implementazione, consulta Condivisione della connessione (multiplexing). Se utilizzi il connettore Beam con semantica "at-least-once": puoi abilitare il multiplexing UseStorageApiConnectionPool. Il connettore Dataproc Spark ha il multiplexing abilitato per impostazione predefinita.
Per ottenere le migliori prestazioni, utilizza una connessione per il maggior numero possibile di scritture di dati. Non utilizzare un'unica connessione per una singola scrittura o aprire e chiudere flussi di dati piccole scritture.
Esiste una quota per il numero
connessioni simultanee che possono essere
contemporaneamente per ogni progetto. Oltre il limite, le chiamate al numero AppendRows
non andranno a buon fine.
Tuttavia, la quota per le connessioni simultanee può essere aumentata e non
di solito un fattore limitante
per la scalabilità.
Ogni chiamata a AppendRows
crea un nuovo oggetto DataWriter. Quindi,
quando si utilizza un flusso creato dall'applicazione, il numero di connessioni corrisponde
e il numero di stream creati. In genere, una singola connessione supporta almeno 1 MBps di throughput. Il limite superiore dipende da
come la larghezza di banda della rete, lo schema dei dati e il carico del server,
può superare i 10 Mbps.
È prevista anche una quota della velocità effettiva totale per progetto. Questo rappresenta i byte al secondo tra tutte le connessioni che passano attraverso Servizio API Storage Scrivi. Se il tuo progetto supera questa quota, puoi richiedere un limite di quota più alto. In genere ciò comporta l'aumento delle quote di accompagnamento, come quelle di connessioni a internet in un rapporto uguale.
Gestire gli offset dello stream per ottenere la semantica esatta
L'API StorageWrite consente le scritture solo fino alla fine corrente che si sposta man mano che vengono aggiunti i dati. La posizione corrente nello stream è specificata come offset dall'inizio dello stream.
Quando scrivi in un flusso creato dall'applicazione, puoi specificare il flusso o offset per ottenere una semantica "exactly-once".
Quando specifichi un offset, l'operazione di scrittura è idempotente, il che la rende riprovare a causa di errori di rete o dell'assenza di risposta del server. Gestisci i seguenti errori relativi agli offset:
ALREADY_EXISTS
(StorageErrorCode.OFFSET_ALREADY_EXISTS
): la riga è stata già scritta. Puoi tranquillamente ignorare questo errore.OUT_OF_RANGE
(StorageErrorCode.OFFSET_OUT_OF_RANGE
): una scrittura precedente operazione non riuscita. Riprova dall'ultima scrittura riuscita.
Tieni presente che questi errori possono verificarsi anche se imposti il valore dell'offset errato, quindi devi gestire attentamente gli offset.
Prima di utilizzare gli offset dello stream, valuta se hai bisogno della semantica esattamente una volta. Ad esempio, se la pipeline di dati upstream garantisce solo almeno una volta, scritture o se riesci a rilevare facilmente i duplicati dopo importazione dati, potrebbero non richiedere una scrittura "exactly-once". In questo caso, ti consigliamo di utilizzare lo stream predefinito, che non richiede il monitoraggio degli offset di riga.
Non bloccare le chiamate AppendRows
Il metodo AppendRows
è asincrono. Puoi inviare una serie di scritture senza
bloccare una risposta per ogni singola scrittura. I messaggi di risposta sulla connessione bidirezionale arrivano nello stesso ordine in cui le richieste sono state inserite in coda.
Per la velocità effettiva massima, chiama AppendRows
senza bloccare per attendere il giorno
la risposta corretta.
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. È comune che lo schema si evolva nel tempo, ad esempio aggiungendo nuovi campi con valori null. Una pipeline solida deve gestire gli aggiornamenti dello schema out-of-band.
L'API StorageWrite supporta gli schemi delle tabelle nel modo seguente:
- La prima richiesta di scrittura include lo schema.
- Ogni riga di dati viene inviata come buffer del protocollo binario. BigQuery mappa i dati allo schema.
- È possibile omettere campi con valori null, ma non è possibile includere campi che non siano
presente 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 la tabella
in BigQuery. L'API StorageWrite rileva
lo schema viene modificato dopo un breve lasso di tempo, nell'ordine dei minuti. Quando
L'API StorageWrite rileva la modifica dello schema,
Il messaggio di risposta di AppendRowsResponse
contiene un
TableSchema
che descrive il nuovo schema.
Per inviare i 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
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 in modo programmatico, chiama
AppendRowsResponse.hasUpdatedSchema
dopo il append
viene completato.
Puoi anche configurare JsonStreamWriter
in modo che ignori i campi sconosciuti in
i dati di input. Per impostare questo comportamento, chiama
setIgnoreUnknownFields
. Questo comportamento è simile all'opzione ignoreUnknownValues
quando si utilizza l'API precedente tabledata.insertAll
. ma può causare una perdita accidentale di dati, in quanto i campi sconosciuti
cadere silenziosamente.