Scritture

Questa pagina elenca i tipi di richieste di scrittura che puoi inviare a Bigtable e descrive quando utilizzarli e quando no.

Le librerie client e l'API Bigtable Data consentono di scrivere dati nelle tabelle in modo programmatico. Bigtable invia una risposta o conferma per ogni scrittura.

Ogni libreria client offre la possibilità di inviare i seguenti tipi di richieste di scrittura:

  • Operazioni di scrittura semplici
  • Incremento e accodamento
  • Scritture condizionali
  • Operazioni di scrittura in batch

Le librerie client di Bigtable dispongono di una funzionalità integrata di nuovi tentativi intelligenti per le scritture semplici e in batch, consentendo di gestire senza problemi l'indisponibilità temporanea. Ad esempio, se l'applicazione tenta di scrivere dati e si verifica un'interruzione temporanea o un problema di rete, riprova automaticamente fino a quando non viene eseguito il commit della scrittura o non viene raggiunta la scadenza della richiesta. Questa resilienza funziona sia con le istanze a cluster singolo che con quelle replicate, con routing a cluster singolo o a cluster multipli.

Per le operazioni di scrittura in batch e flussi, puoi utilizzare il [ connettore Bigtable Beam . Per ulteriori informazioni, consulta Operazioni di scrittura in batch.

Per scoprire di più sui limiti che si applicano alle richieste di scrittura, consulta Quote e limiti.

Per ogni libreria client di Cloud Bigtable sono disponibili esempi per ogni tipo di scrittura.

Per informazioni su come aggiungere dati alle celle di aggregazione, consulta Valori aggregati al momento della scrittura (anteprima).

Tipi di operazioni di scrittura e quando utilizzarle

Tutte le richieste di scrittura includono i seguenti componenti di base:

  • Il nome della tabella in cui scrivere.
  • Un ID profilo di app che indica a Bigtable come indirizzare il traffico.
  • Una o più mutazioni. Una mutazione è composta da quattro elementi:
    • Nome famiglia di colonne
    • Qualificatore colonna
    • Timestamp
    • Valore che stai scrivendo nella tabella

Il timestamp di una mutazione ha un valore predefinito della data e dell'ora correnti, misurato come il tempo trascorso dall'epoca di Unix, 00:00:00 UTC, il 1° gennaio 1970.

Un timestamp inviato a Bigtable deve essere un valore in microsecondi con una precisione massima di un millisecondo. Un timestamp con precisione in microsecondi, ad esempio 3023483279876543, viene rifiutato. In questo esempio, il valore accettabile per il timestamp è 3023483279876000.

Tutte le mutazioni in una singola richiesta di scrittura hanno lo stesso timestamp, a meno che non le sostituisci. Puoi impostare il timestamp di tutte le mutazioni in una richiesta di scrittura in modo che sia uguale o diverso l'una dall'altra.

Operazioni di scrittura semplici

Puoi scrivere una singola riga in Bigtable con una richiesta MutateRow che include il nome della tabella, l'ID del profilo dell'app da utilizzare, una chiave di riga e fino a 100.000 modifiche per la riga in questione. Una scrittura su riga singola è atomica. Utilizza questo tipo di scrittura quando apporti più mutazioni a una singola riga.

Per esempi di codice che mostrano come inviare richieste di scrittura semplici, consulta Esecuzione di una scrittura semplice.

Quando non utilizzare scritture semplici

Una scrittura semplice non è il modo migliore per scrivere dati per i seguenti casi d'uso:

  • Stai scrivendo un batch di dati che avrà chiavi di riga contigue. In questo caso, dovresti utilizzare le scritture batch anziché semplici scritture consecutive, poiché è possibile applicare un batch contiguo a una singola chiamata di backend.

  • Vuoi una velocità effettiva elevata (righe al secondo o byte al secondo) e non richiedono una bassa latenza. In questo caso, le scritture in batch saranno più rapide.

Incremento e accodamento

In molti casi, l'utilizzo di aggregati (anteprima), che consente di aggiornare un valore al momento della scrittura, è l'opzione migliore nei casi in cui vuoi aumentare o aumentare un valore. Tuttavia, i dati aggregati non supportano le operazioni di aggiunta. Per ulteriori informazioni, consulta Valori aggregati al momento della scrittura.

Se vuoi aggiungere dati a un valore esistente o devi incrementare un valore numerico esistente e non puoi utilizzare i dati aggregati, puoi inviare una richiesta ReadModifyWriteRow. Questa richiesta include il nome della tabella, l'ID del profilo dell'app da utilizzare, una chiave di riga e un insieme di regole da utilizzare durante la scrittura dei dati. Ogni regola include il nome della famiglia di colonne, il qualificatore di colonna e un valore aggiunto o un importo dell'incremento.

Le regole vengono applicate in ordine. Ad esempio, se la tua richiesta include una richiesta di aumentare di due il valore di una colonna e una regola successiva nella stessa richiesta incrementa di 1 la stessa colonna, la colonna viene incrementata di 3 in questa singola scrittura atomica. La regola successiva non sovrascrive la regola precedente.

Un valore può essere incrementato solo se viene codificato come numero intero con firma big-endian a 64 bit. Bigtable tratta un incremento a un valore vuoto o non esistente come se il valore fosse zero. Le richieste ReadModifyWriteRow sono atomiche. Non vengono tentati nuovamente se non riescono per qualsiasi motivo.

Per esempi di codice che mostrano come aggiungere un valore in una cella, consulta Incremento di un valore esistente.

Quando non utilizzare ReadModifyWriteRow

Non devi inviare richieste ReadModifyWriteRow nelle seguenti situazioni:

  • Il tuo caso d'uso può essere gestito con i aggregate (anteprima).

  • Stai utilizzando un profilo dell'app con routing a cluster multipli.

  • Stai utilizzando più profili di app a cluster singolo e stai inviando scritture che potrebbero entrare in conflitto con i dati scritti nella stessa riga e colonna in altri cluster dell'istanza. Con il routing a cluster singolo, una richiesta di scrittura viene inviata a un singolo cluster e poi replicata.

  • Fai affidamento sulla funzionalità di nuovi tentativi intelligenti fornita dalle librerie client. Gli incrementi e le aggiunte non sono ripristinabili.

  • Stai scrivendo grandi quantità di dati e hai bisogno che le scritture vengano completate rapidamente. Una richiesta che legge e poi modifica una riga è più lenta di una semplice richiesta di scrittura. Di conseguenza, questo tipo di scrittura spesso non è l'approccio migliore su larga scala. Ad esempio, se vuoi conteggiare un elemento che verrà numerato in milioni, come le visualizzazioni di pagina, devi utilizzare i dati aggregati per aggiornare i conteggi al momento della scrittura. Potresti anche considerare la registrazione di ogni vista come semplice scrittura anziché incrementare un valore, per poi utilizzare un job Dataflow per aggregare i dati.

Scritture condizionali

Se vuoi verificare la presenza di una condizione in una riga e poi, a seconda del risultato, scrivere dati nella riga, invia una richiesta CheckAndMutateRow. Questo tipo di richiesta include una chiave di riga e un filtro di riga. Un filtro di riga è un insieme di regole utilizzate per verificare il valore dei dati esistenti. Le mutazioni vengono quindi applicate a colonne specifiche della riga solo quando vengono soddisfatte determinate condizioni, verificate dal filtro. Questo processo di controllo e scrittura viene completato come una singola azione atomica.

Una richiesta di filtro deve includere uno o entrambi i tipi di mutazioni:

  • Mutazioni reali o mutazioni da applicare se il filtro restituisce un valore.
  • False mutazioni, che vengono applicate se il filtro non restituisce nulla.

Puoi fornire fino a 100.000 di ogni tipo di mutazione (vero e falso) in una singola scrittura e devi inviarne almeno una. Bigtable invia una risposta quando tutte le mutazioni sono complete.

Per esempi di codice che mostrano come inviare scritture condizionali, consulta Scrittura condizionale di un valore.

Quando non utilizzare le scritture condizionali

Non puoi utilizzare le scritture condizionali per il seguente caso d'uso:

  • Stai utilizzando un profilo dell'app con routing multi-cluster.

  • Stai utilizzando più profili di app a cluster singolo e stai inviando scritture che potrebbero entrare in conflitto con i dati scritti nella stessa riga e colonna in altri cluster dell'istanza. Con il routing a cluster singolo, una richiesta di scrittura viene inviata a un singolo cluster e poi replicata.

Operazioni di scrittura in batch

Puoi scrivere più di una riga con una singola chiamata utilizzando una richiesta MutateRows. Le richieste MutateRows contengono un insieme di massimo 100.000 voci applicate a livello atomico. Ogni voce è composta da una chiave di riga e da almeno una modifica da applicare alla riga. Una richiesta di scrittura batch può contenere fino a 100.000 mutazioni in tutte le voci. Ad esempio, una scrittura batch potrebbe includere una qualsiasi delle seguenti permutazioni:

  • 100.000 voci con 1 mutazione in ciascuna voce.
  • 1 voce con 100.000 mutazioni.
  • 1000 voci con 100 mutazioni ciascuna.

Ogni voce in una richiesta MutateRows è atomica, ma l'intera richiesta non lo è. Se necessario, Bigtable esegue un nuovo tentativo nel batch di eventuali voci non riuscite, finché tutte le scritture non andranno a buon fine o non verrà raggiunta la scadenza della richiesta. Quindi restituisce una risposta che identifica ogni scrittura nel batch e indica se la scrittura è riuscita o meno.

Per esempi di codice che mostrano come inviare scritture batch, consulta Esecuzione di scritture batch.

Quando non utilizzare le scritture batch

  • Stai scrivendo dati in blocco in righe non vicine tra loro. Bigtable archivia i dati lessicograficamente per chiave di riga, l'equivalente binario in ordine alfabetico. Per questo motivo, quando le chiavi di riga di una richiesta non sono simili tra loro, Bigtable le gestisce in sequenza, anziché in parallelo. La velocità effettiva sarà elevata, ma anche la latenza sarà elevata. Per evitare un'elevata latenza, utilizza MutateRows quando le chiavi di riga sono simili e Bigtable scriverà righe vicine tra loro. Utilizza MutateRow, o scritture semplici, per le righe che non sono vicine tra loro.

  • Stai richiedendo più modifiche alla stessa riga. In questo caso, vedrai prestazioni migliori se esegui tutte le mutazioni in una singola semplice richiesta di scrittura. Questo perché, in una semplice scrittura, viene eseguito il commit di tutte le modifiche in una singola azione atomica, ma una scrittura in batch viene forzata per serializzare le mutazioni nella stessa riga, causando latenza.

Controllo del flusso in scrittura batch

Se invii le scritture batch utilizzando uno dei seguenti metodi, puoi abilitare il controllo del flusso di scrittura in batch nel codice.

Quando il controllo del flusso di scrittura in batch è abilitato per un job Dataflow, Bigtable esegue automaticamente le seguenti operazioni :

  • Limita il traffico per evitare il sovraccarico del cluster Bigtable
  • Garantisce che il cluster abbia un carico sufficiente per attivare la scalabilità automatica di Bigtable (se abilitata), in modo che vengano aggiunti automaticamente più nodi al cluster quando necessario.

Queste azioni combinate prevengono il sovraccarico del cluster e gli errori del job e non è necessario scalare manualmente il cluster in previsione dell'esecuzione della scrittura batch. Quando il controllo del flusso è abilitato, la scalabilità del cluster avviene durante il job di Dataflow anziché prima, pertanto il completamento del job potrebbe richiedere più tempo rispetto a quando scala il cluster manualmente.

Devi utilizzare un profilo dell'app configurato per il routing a cluster singolo. L'abilitazione della scalabilità automatica di Bigtable per il cluster di destinazione non è un requisito, ma la scalabilità automatica consente di sfruttare appieno il controllo del flusso di scrittura batch. Puoi utilizzare la scalabilità automatica di Dataflow come faresti con qualsiasi altro job.

Per scoprire di più sulla scalabilità automatica di Bigtable, consulta Scalabilità automatica. Per comprendere i criteri di routing dei profili di app, consulta Panoramica dei profili di app.

Per un esempio di codice che mostra come abilitare il controllo del flusso di scrittura batch utilizzando il connettore Beam HBase di Bigtable, consulta Scrittura in Bigtable.

Scrivere dati in una vista autorizzata

Per scrivere dati in una vista autorizzata, devi utilizzare uno dei seguenti elementi:

  • Interfaccia a riga di comando gcloud
  • Client Bigtable per Java

Le altre librerie client di Bigtable non supportano ancora l'accesso in visualizzazione autorizzato.

Quando scrivi dati in una vista autorizzata, oltre all'ID tabella devi fornire l'ID visualizzazione autorizzata.

Tutte le scritture in una visualizzazione autorizzata vengono applicate direttamente alla tabella sottostante.

Limitazioni della definizione di visualizzazioni autorizzate

In una vista autorizzata, le righe o le colonne in cui puoi scrivere dati sono limitate dalla definizione della vista autorizzata. In altre parole, puoi scrivere solo in righe e colonne che soddisfano gli stessi criteri specificati per la visualizzazione autorizzata.

Ad esempio, se la vista autorizzata è definita dal prefisso della chiave di riga examplepetstore1, non puoi scrivere dati utilizzando una chiave di riga di examplepetstore2; l'inizio della coppia chiave-valore di riga deve includere l'intera stringa examplepetstore1.

Allo stesso modo, se la vista autorizzata è definita dal prefisso del qualificatore di colonna order-phone, puoi scrivere i dati utilizzando il qualificatore di colonna order-phone123, ma non puoi utilizzare il qualificatore di colonna order-tablet.

Inoltre, la richiesta di scrittura non può fare riferimento a dati al di fuori della visualizzazione autorizzata, ad esempio quando controlli un valore in una richiesta di scrittura condizionale.

Per qualsiasi richiesta che scrive o faccia riferimento a dati al di fuori della visualizzazione autorizzata, viene restituito un messaggio di errore PERMISSION_DENIED.

Replica

Quando un cluster di un'istanza replicata riceve una scrittura, questa viene immediatamente replicata negli altri cluster dell'istanza.

Atomicità

Ogni richiesta MutateRows inviata a un'istanza replicata viene impegnata come singola azione atomica sul cluster a cui viene instradata la richiesta. Quando la scrittura viene replicata negli altri cluster dell'istanza, anche questi ricevono la scrittura come operazione atomica. I cluster non ricevono mutazioni parziali; una mutazione ha successo o meno a livello atomico per tutte le cellule che modifica.

Coerenza

Il tempo necessario affinché i dati scritti siano disponibili per le letture dipende da diversi fattori, tra cui il numero di cluster nell'istanza e il tipo di routing utilizzato dal profilo dell'app. Con un'istanza a cluster singolo, i dati possono essere letti immediatamente, ma se un'istanza ha più di un cluster, ovvero che utilizza la replica, Bigtable è finalmente coerente. Puoi raggiungere una coerenza delle operazioni di lettura e scrittura instradando le richieste allo stesso cluster.

Puoi creare e utilizzare un token di coerenza e chiamare CheckConsistency in modalità StandardReadRemoteWrites dopo aver inviato le richieste di scrittura. Il token verifica la coerenza della replica. In generale, si crea un token di coerenza dopo l'invio di un batch di scritture o dopo un determinato intervallo, ad esempio un'ora. Quindi puoi passare il token affinché venga utilizzato da un altro processo, ad esempio un modulo che effettua una richiesta di lettura, in modo da utilizzare il token per verificare che tutti i dati siano stati replicati prima che provi a leggere.

Se utilizzi un token subito dopo averlo creato, potrebbero essere necessari alcuni minuti per verificarne la coerenza la prima volta che lo utilizzi. Questo ritardo è dovuto al fatto che ogni cluster controlla gli altri cluster per garantire che non arrivino altri dati. Dopo l'utilizzo iniziale o se attendi diversi minuti per utilizzare il token per la prima volta, il token ha esito positivo immediatamente ogni volta che viene utilizzato.

Risoluzione dei conflitti

Ogni valore di cella in una tabella Bigtable è identificato in modo univoco da quattro tuple (chiave di riga, famiglia di colonne, qualificatore di colonna, timestamp). Per ulteriori dettagli su questi identificatori, consulta Modello di archiviazione Bigtable. Nel raro caso in cui due scritture con le stesse quattro tuple vengano inviate a due cluster diversi, Bigtable risolve automaticamente il conflitto utilizzando un algoritmo interno l'ultima scrittura vince in base al tempo lato server. L'implementazione "l'ultima scrittura vince" di Bigtable è deterministica e, quando la replica raggiunge il valore, tutti i cluster hanno lo stesso valore per la quattro tupla.

Passaggi successivi