Best practice per l'API BigQuery Storage Scrivi

Questo documento fornisce le best practice per l'utilizzo dell'API BigQuery Storage Writer. Prima del giorno leggere questo documento, leggere Panoramica dell'API BigQuery Storage Scrivi.

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 i flussi di dati creati dall'applicazione, evita di chiamare CreateWriteStream a un livello elevato frequenza. In genere, se superi le 40-50 chiamate al secondo, la latenza del Le chiamate API crescono notevolmente (più di 25 secondi). 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 chiamata da completare, 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 usi il flusso predefinito, puoi usare l'API Storage Scrivi multiplexing per scrivere in più tabelle di destinazione con connessioni condivise. Connessioni dei pool di multiplexing per una migliore velocità effettiva e utilizzo Google Cloud. Se il flusso di lavoro ha più di 20 connessioni simultanee, è consigliabile di usare il multiplexing. multiplexing disponibile in Java e Go. Per i dettagli sull'implementazione 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. Dataproc Spark con multiplexing abilitato per impostazione predefinita.

Per ottenere prestazioni ottimali, 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 writer. 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 una velocità effettiva di almeno 1 Mbps. 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ù elevato. In genere ciò comporta l'aumento delle quote di accompagnamento, come quelle di connessioni a 100 nodi, in un rapporto uguale.

Gestisci gli offset dei flussi per ottenere una semantica "exactly-once"

L'API StorageWrite consente le scritture solo fino alla fine corrente che si sposta man mano che vengono aggiunti i dati. La posizione attuale nello stream è specificato come offset dall'inizio del flusso.

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 era sono già stati scritti. Puoi tranquillamente ignorare questo errore.
  • OUT_OF_RANGE (StorageErrorCode.OFFSET_OUT_OF_RANGE): una scrittura precedente operazione non riuscita. Riprova dall'ultima scrittura riuscita.

Nota che questi errori possono verificarsi anche se si imposta un valore di offset errato, quindi gestire con attenzione le compensazioni.

Prima di utilizzare gli offset di flusso, valuta se è necessaria la semantica "exactly-once". Ad esempio, se la pipeline di dati upstream garantisce solo almeno una volta, o se riesci a rilevare facilmente i duplicati dopo importazione dati, potrebbero non richiedere una scrittura "exactly-once". In tal caso, consigliamo di utilizzare flusso predefinito, che non richiede il monitoraggio degli offset di riga.

Non bloccare per 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 nella le connessioni bidirezionali arrivano nello stesso ordine in cui le richieste sono state accodate. Per la velocità effettiva massima, chiama AppendRows senza bloccare per attendere il giorno risposta.

Gestire gli aggiornamenti dello schema

Per scenari di flussi di dati, gli schemi delle tabelle vengono generalmente gestiti al di fuori pipeline di flusso. È comune che lo schema si evolva nel tempo, ad esempio aggiungendo nuovi campi con valori null. Una pipeline robusta deve gestire lo schema fuori banda aggiornamenti.

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.
  • Puoi omettere campi con valori null, ma non puoi includere campi che non siano presente nello schema attuale. Se invii righe con campi aggiuntivi, L'API StorageWrite restituisce StorageError con StorageErrorCode.SCHEMA_MISMATCH_EXTRA_FIELD.

Se vuoi inviare nuovi campi nel payload, devi prima aggiornare la tabella in BigQuery. L'API Storage Scrivi 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 il giorno un aggiornamento dello schema, JsonStreamWriter si riconnette automaticamente con schema aggiornato. Non è necessario chiudere e riaprire la connessione in modo esplicito. 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 a l'opzione ignoreUnknownValues quando viene utilizzata la versione precedente tabledata.insertAll API. Tuttavia, può causare la perdita accidentale di dati, poiché i campi sconosciuti cadere silenziosamente.