Scritture

In questa pagina sono elencati i tipi di richieste di scrittura che puoi inviare a Bigtable e viene descritto quando e quando non utilizzarli. Per informazioni sull'aggregazione dei dati in una cella in fase di scrittura, consulta Valori aggregati al momento della scrittura (anteprima).

L'API Bigtable Data e le librerie client consentono di scrivere in modo programmatico i dati nelle tabelle. Bigtable restituisce una risposta o una conferma per ogni scrittura.

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

  • Scritture semplici
  • Incrementi e aggiunte
  • Scritture condizionali
  • Scritture batch

Le librerie client di Bigtable dispongono di una funzionalità integrata di tentativi intelligenti per scritture semplici e batch, il che significa che gestiscono senza problemi l'indisponibilità temporanea. Ad esempio, se l'applicazione tenta di scrivere dati e riscontra un'interruzione temporanea o un problema di rete, fa un nuovo tentativo automatico 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 il routing a cluster singolo o multi-cluster.

Per le operazioni di scrittura in batch e in flussi, puoi usare il connettore Bigtable Beam. Per ulteriori informazioni, consulta Scritture in batch.

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

Per esempi di libreria client di Cloud Bigtable delle richieste di scrittura descritte in questa pagina, consulta Esempi di scrittura.

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 dell'app, che indica a Bigtable come instradare il traffico.
  • Una o più mutazioni. Una mutazione è composta dai seguenti elementi:
    • Nome famiglia di colonne
    • Qualificatore colonna
    • Timestamp
    • Valore che stai scrivendo nella tabella

Il timestamp di una mutazione ha un valore predefinito corrispondente alla data e all'ora correnti, misurata come tempo trascorso dall'epoca di Unix, 00:00:00 UTC, 1° gennaio 1970.

Il timestamp inviato a Bigtable deve essere un valore in microsecondi con una precisione massima di un millisecondo. Un timestamp con precisione in microsecondi, come 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'uno dall'altro.

Scritture 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 mutazioni per quella riga. Una scrittura su riga singola è atomica. Utilizza questo tipo di scrittura quando apporti più mutazioni a una singola riga.

Per gli esempi di codice che dimostrano come inviare richieste di scrittura semplici, consulta Eseguire una scrittura semplice.

Quando non usare scritture semplici

Le operazioni di scrittura semplici non sono 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, devi utilizzare le scritture batch invece di semplici scritture consecutive, poiché un batch contiguo può essere applicato in un'unica chiamata di backend.

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

Incrementi e aggiunte

Quando vuoi aumentare o incrementare un valore, l'opzione migliore è utilizzare gli aggregati, che consentono di aggiornare un valore in fase di scrittura. Gli aggregati non supportano le operazioni di aggiunta. Per maggiori informazioni, consulta Valori aggregati in fase di scrittura (anteprima).

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 di aggiunta o un importo di incremento.

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

Un valore può essere incrementato solo se è codificato come numero intero con segno big-endian a 64 bit. Bigtable tratta un incremento per un valore vuoto o che non esiste come se il valore fosse zero. Le richieste ReadModifyWriteRow sono atomiche. Non verranno riprovati se non superano l'upgrade per qualsiasi motivo.

Per gli esempi di codice che dimostrano come aggiungere un valore in una cella, consulta Aumento di un valore esistente.

Quando non usare ReadModifyWriteRow

Non inviare richieste ReadModifyWriteRow nelle seguenti situazioni:

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

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

  • Stai utilizzando più profili di app a cluster singolo e stai inviando scritture che potrebbero essere 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.

  • Ti affidi alla funzionalità dei tentativi intelligenti fornita dalle librerie client. Non è possibile riprovare con incrementi e aggiunte.

  • 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 qualcosa che corrisponda ai milioni, come le visualizzazioni di pagina, devi utilizzare i aggregati per aggiornare i conteggi al momento della scrittura. Potresti anche registrare ogni vista come una semplice scrittura, anziché incrementare un valore, e poi utilizzare un job Dataflow per aggregare i dati.

Scritture condizionali

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

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

  • Mutazioni vere o le 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, di cui devi inviarne almeno una. Bigtable invia una risposta quando tutte le mutazioni sono complete.

Per gli esempi di codice che dimostrano come inviare scritture condizionali, consulta Scrivere un valore in modo condizionale.

Quando non utilizzare le scritture condizionali

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

  • Stai utilizzando un profilo app con routing su cluster multipli.

  • Stai utilizzando più profili di app a cluster singolo e stai inviando scritture che potrebbero essere 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.

  • Stai scrivendo grandi quantità di dati e hai bisogno che le scritture vengano completate rapidamente. Analogamente a ReadModifyWriteRow, le richieste di scrittura condizionali devono leggere le righe prima di modificarle, quindi le richieste CheckAndModifyRow sono più lente delle semplici richieste di scrittura. Di conseguenza, questo tipo di scrittura spesso non è l'approccio migliore su larga scala.

Scritture 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 in modo atomico. Ogni voce è composta da una chiave di riga e da almeno una mutazione da applicare alla riga. Una richiesta di scrittura batch può contenere fino a 100.000 mutazioni distribuite 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 la richiesta nel suo complesso non lo è. Se necessario, Bigtable effettua un nuovo tentativo con le voci del batch che non vanno a buon fine, fino a quando tutte le scritture non sono andate a buon fine o fino a quando la scadenza della richiesta non viene raggiunta. Quindi restituisce una risposta che identifica ogni scrittura nel batch e se la scrittura è riuscita o meno.

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

Quando non utilizzare le scritture in batch

  • Stai scrivendo dati in blocco su righe non vicine tra loro. Bigtable archivia i dati in ordine alfabetico in base alla 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 questa elevata latenza, utilizza MutateRows se le chiavi di riga sono simili e Bigtable scriverà righe vicine tra loro. Utilizza MutateRow, o semplici scritture, per le righe non vicine tra loro.

  • Stai richiedendo più mutazioni per la stessa riga. In questo caso, le prestazioni saranno migliori se esegui tutte le mutazioni in una singola richiesta di scrittura semplice. Questo perché, in una semplice scrittura, tutte le modifiche vengono eseguite in una singola azione atomica, ma una scrittura batch è forzata a serializzare le mutazioni nella stessa riga, causando latenza.

Controllo del flusso di scrittura batch

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

Quando il controllo del flusso di scrittura batch è abilitato per un job Dataflow, Bigtable esegue automaticamente quanto segue :

  • Limita la frequenza del traffico per evitare di sovraccaricare il 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 altri nodi al cluster quando necessario

Queste azioni combinate evitano il sovraccarico del cluster e gli errori dei job, senza la necessità di 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 Dataflow anziché prima, quindi il completamento del job potrebbe richiedere più tempo rispetto alla scalabilità manuale del cluster.

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

Per saperne di più sulla scalabilità automatica di Bigtable, consulta Scalabilità automatica. Per comprendere i criteri di routing dei profili app, vedi Panoramica dei profili 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.

Scrivi dati in una vista autorizzata

Per scrivere i dati in una vista autorizzata, devi utilizzare una delle seguenti opzioni:

  • 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, fornisci l'ID vista autorizzata oltre all'ID tabella.

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

Limitazioni della definizione delle viste 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 nelle righe e nelle 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 examplepetstore2; l'inizio del valore della chiave 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 tua 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 fa riferimento a dati al di fuori della visualizzazione autorizzata, viene restituito un messaggio di errore di 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 ultimi ricevono la scrittura come operazione atomica. I cluster non ricevono mutazioni parziali; una mutazione ha esito positivo o negativo a livello atomico per tutte le cellule modificate.

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, il che significa che utilizza la replica, Bigtable è alla fine coerente. Puoi ottenere la coerenza in operazioni di lettura/scrittura instradando le richieste allo stesso cluster.

Puoi creare e utilizzare un token di coerenza e chiamare CheckConsistency in modalità StandardReadRemoteWrites dopo aver inviato richieste di scrittura. Il token controlla la coerenza della replica. In generale, puoi creare un token di coerenza dopo l'invio di un batch di scritture o dopo un determinato intervallo, ad esempio un'ora. Puoi quindi trasferire il token affinché venga utilizzato da un altro processo, ad esempio un modulo che effettua una richiesta di lettura, che utilizza il token per verificare che tutti i dati siano stati replicati prima di tentare di leggerli.

Se utilizzi un token subito dopo averlo creato, la prima volta che utilizzi un token, potrebbero essere necessari alcuni minuti per verificarne la coerenza. Questo ritardo è dovuto al fatto che ogni cluster controlla ogni altro cluster per assicurarsi che non siano disponibili altri dati. Dopo l'utilizzo iniziale o se attendi diversi minuti prima di utilizzarlo per la prima volta, il token riesce immediatamente ogni volta che viene utilizzato.

Risoluzione dei conflitti

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

Passaggi successivi