Scritture
Questa pagina elenca i tipi di richieste di scrittura che puoi inviare a Bigtable e descrive quando utilizzarle e quando no. Per informazioni sull'aggregazione dei dati in una cella al momento della scrittura, consulta Aggregare i valori al momento della scrittura.
L'API Bigtable Data e le librerie client ti consentono di scrivere i dati nelle tue tabelle in modo programmatico. Bigtable invia una risposta o un 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à di ripetizione intelligente integrata per le scritture semplici e in batch, il che significa che gestiscono senza problemi l'eventuale temporanea indisponibilità. Ad esempio, se la tua applicazione tenta di scrivere dati e si verifica un'interruzione temporanea o un problema di rete, riprova automaticamente fino a quando la scrittura non viene confermata o non viene raggiunta la scadenza della richiesta. Questa resilienza funziona sia con istanze a cluster singolo che con istanze replicate, con routing a cluster singolo o a cluster multipli.
Per le operazioni di scrittura in batch e in streaming, puoi utilizzare il connettore Bigtable Beam. Per ulteriori informazioni, consulta la sezione Scritture collettive.
Per informazioni sui limiti che si applicano alle richieste di scrittura, consulta Quote e limiti.
Per esempi di richieste di scrittura della libreria client Cloud Bigtable descritte in questa pagina, consulta Esempi di scrittura.
Tipi di scrittura e quando utilizzarli
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 è costituita dai seguenti elementi:
- Nome famiglia di colonne
- Qualificatore di colonna
- Timestamp
- Valore da scrivere nella tabella
Il timestamp di una mutazione ha un valore predefinito pari alla data e all'ora correnti, misurato come tempo trascorso dall'epoca di Unix, 00:00:00 UTC il 1° gennaio 1970.
Un timestamp inviato a Bigtable deve essere espresso con un valore in microsecondi e una precisione massima di un millisecondo. Un timestamp con precisione in microsecondi, ad esempio3023483279876543
, 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 di una singola riga è atomica. Utilizza questo tipo di scrittura quando apporti più mutazioni a una singola riga.
Per esempi di codice che mostrano come inviare semplici richieste di scrittura, consulta Eseguire una scrittura semplice.
Quando non utilizzare le scritture semplici
Le scritture 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 anziché le scritture semplici consecutive, perché un batch contiguo può essere applicato in una singola chiamata di backend.
Ti serve una velocità effettiva elevata (righe al secondo o byte al secondo) e non hai bisogno di una bassa latenza. In questo caso, le scritture collettive saranno più veloci.
Aggregazioni, inclusi gli incrementi
Gli aggregati sono celle di tabelle Bigtable che aggregano i valori delle celle man mano che i dati vengono scritti. Sono disponibili i seguenti tipi di aggregazione:
- Somma: incrementa un contatore o mantieni una somma parziale.
- Minimo: invia un numero intero a una cella e Bigtable conserva il valore più basso tra il valore corrente della cella e il valore inviato oppure il valore inviato se la cella non esiste ancora.
- Massimo: invia un numero intero a una cella contenente un valore e Bigtable conserva il valore più alto dei due.
- HyperLogLog (HLL): invia un valore che viene aggiunto a un insieme probabilistico di tutti i valori aggiunti alla cella.
Le richieste di aggiornamento delle celle aggregate vengono inviate con una richiesta MutateRow
e un tipo di mutazione AddToCell
o MergeToCell
o uno dei tipi di mutazione di eliminazione. Per ulteriori informazioni sulle famiglie di colonne aggregate e sui tipi di aggregazione, consulta Aggregare i valori al momento della scrittura.
Aggiunta
Per accodare i dati a un valore esistente, puoi utilizzare 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 per scrivere i dati. Ogni regola include il nome della famiglia di colonne, il qualificatore di colonna e un valore di accodamento o un importo di incremento.
Le regole vengono applicate in ordine. Ad esempio, se la richiesta include una richiesta di
aggiunzione del valore di una colonna contenente il valore some
con la stringa
thing
e una regola successiva nella stessa richiesta aggiunge la stessa colonna con
body
, il valore viene modificato due volte in una singola scrittura atomica e il valore risultante è somethingbody
. La regola successiva non sovrascrive quella precedente.
Puoi anche incrementare un numero intero con una chiamata ReadModifyWriteRow
, ma ti consigliamo di utilizzare le celle aggregate e AddToCell
o MergeToCell
.
Un valore può essere incrementato utilizzando ReadModifyWrite
solo se è codificato come
numero intero a 64 bit big endian. Bigtable tratta un incremento di un valore vuoto o non esistente come se il valore fosse zero.
Le richieste ReadModifyWriteRow
sono atomiche. Non viene eseguito alcun nuovo tentativo se non riescono per qualsiasi motivo.
Quando non utilizzare ReadModifyWriteRow
Non inviare richieste ReadModifyWriteRow
nelle seguenti situazioni:
Il tuo caso d'uso può essere gestito inviando una richiesta
MutateRow
con una mutazioneAddToCell
. Per ulteriori informazioni, consulta la sezione Aggregazioni.Stai utilizzando un profilo dell'app con routing a cluster multipli.
Utilizzi più profili dell'app a cluster singolo e invii scritture che potrebbero entrare in conflitto con i dati scritti nella stessa riga e colonna in altri cluster dell'istanza. Con il routing a un cluster singolo, una richiesta di scrittura viene inviata a un singolo cluster e poi replicata.
Ti affidi alla funzionalità di ripetizioni intelligenti fornita dalle librerie client. Non è possibile riprovare a inviare una richiesta
ReadModifyWriteRow
.Stai scrivendo grandi quantità di dati e devi completare le scritture 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 contare qualcosa che si misura in milioni, come le visualizzazioni di pagina, devi
MutateRow
con una mutazioneAddToCell
per aggiornare i conteggi al momento della scrittura.
Scritture condizionali
Se vuoi verificare la presenza di una condizione in una riga e poi, a seconda del risultato, scrivere dati in quella riga, invia una richiesta CheckAndMutateRow
. Questo tipo di
richiesta include una chiave di riga e un filtro per riga. Un filtro riga è un insieme di regole
che utilizzi per controllare il valore dei dati esistenti. Le mutazioni vengono quindi committate
in colonne specifiche della riga solo quando vengono soddisfatte determinate condizioni, controllate dal
filtro. Questo processo di controllo e scrittura viene completato come singola azione atomica.
Una richiesta di filtro deve includere uno o entrambi i seguenti tipi di mutazioni:
- Mutazioni vere o le mutazioni da applicare se il filtro restituisce un valore.
- Mutazioni false, che vengono applicate se il filtro non restituisce risultati.
Puoi specificare fino a 100.000 di ogni tipo di mutazione (true e false) in un singolo inserimento e devi inviarne almeno una. Bigtable invia una risposta al termine di tutte le mutazioni.
Per esempi di codice che mostrano come inviare scritture condizionali, consulta Scrittura di 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 dell'app con routing a cluster multipli.
Utilizzi più profili di app a cluster singolo e invii scritture che potrebbero entrare in conflitto con i dati scritti nella stessa riga e colonna in altri cluster dell'istanza. Con il routing a un cluster singolo, una richiesta di scrittura viene inviata a un singolo cluster e poi replicata.
Stai scrivendo grandi quantità di dati e devi completare le scritture rapidamente. Analogamente a
ReadModifyWriteRow
, le richieste di scrittura condizionale devono leggere le righe prima di modificarle, pertanto le richiesteReadModifyWriteRow
sono più lente delle richieste di scrittura semplici.CheckAndModifyRow
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,ciascuna applicata in modo atomico. Ogni voce è composta da una chiave di riga e da almeno una mutazione da applicare alla riga. Una richiesta di scrittura collettiva può contenere fino a 100.000 mutazioni distribuite tra tutte le voci. Ad esempio, una scrittura batch potrebbe includere una delle seguenti permutazioni:
- 100.000 voci con 1 mutazione in ogni voce.
- 1 voce con 100.000 mutazioni.
- 1000 voci con 100 mutazioni ciascuna.
Ogni voce di una richiesta MutateRows
è atomica, ma la richiesta nel suo insieme non lo è. Se necessario, Bigtable riprova tutte le voci del batch che non vanno a buon fine fino a quando tutte le scritture non vanno a buon fine o non viene raggiunta la scadenza della richiesta. Poi 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 collettive, consulta Eseguire scritture collettive.
Quando non utilizzare le scritture collettive
Stai scrivendo dati collettivi in righe non vicine. Bigtable archivia i dati in ordine lessicografico in base alla chiave di riga, l'equivalente binario dell'ordine alfabetico. Per questo motivo, quando le chiavi di riga in una richiesta non sono simili tra loro, Bigtable le gestisce in sequenza anziché in parallelo. La velocità effettiva sarà elevata, ma anche la latenza. Per evitare questa elevata latenza, utilizza
MutateRows
quando le chiavi di riga sono simili e Bigtable scrive righe vicine tra loro. UtilizzaMutateRow
o semplici scritture per le righe non vicine tra loro.Stai richiedendo più mutazioni per la stessa riga. In questo caso, noterai un miglioramento delle prestazioni se esegui tutte le mutazioni in una singola richiesta di scrittura semplice. Questo perché in una scrittura semplice tutte le modifiche vengono committate in un'unica azione atomica, ma una scrittura batch è costretta a serializzare le mutazioni nella stessa riga, causando latenza.
Controllo del flusso di scrittura batch
Se invii le scritture collettive utilizzando uno dei seguenti metodi, puoi attivare il controllo del flusso di scrittura collettiva nel codice.
- Connettore Bigtable Beam (
BigtableIO
) - Libreria client Bigtable per Java
- Connettore Beam Bigtable HBase (
CloudBigtableIO
) - Client Bigtable HBase per Java
Quando il controllo del flusso di scrittura batch è abilitato per un job Dataflow, Bigtable esegue automaticamente quanto segue :
- Imposta un limite di velocità per il traffico per evitare di sovraccaricare il cluster Bigtable
- Garantisce che il carico del cluster sia sufficiente per attivare la scalabilità automatica di Bigtable (se abilitata), in modo che altri nodi vengano aggiunti automaticamente al cluster in caso di necessità
Queste azioni combinate impediscono il sovraccarico del cluster e il fallimento del job e non è necessario eseguire lo scale del cluster in previsione dell'esecuzione della scrittura batch. Quando il controllo flusso è attivato, la scalabilità del cluster avviene durante il job Dataflow anziché prima, pertanto 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. L'attivazione della scalabilità automatica di Bigtable per il cluster di destinazione non è un requisito, ma la scalabilità automatica ti 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 le norme di routing dei profili di app, consulta la Panoramica dei profili di app.
Per esempi di codice, vedi Abilitare il controllo del flusso di scrittura batch.
Scrivere dati in una vista autorizzata
Per scrivere dati in una visualizzazione autorizzata, devi utilizzare uno dei seguenti elementi:
- Interfaccia a riga di comando gcloud
- Client Bigtable per Java
Le altre librerie client Bigtable non supportano ancora l'accesso alle visualizzazioni autorizzate.
Quando scrivi dati in una vista autorizzata, fornisci l'ID della vista autorizzata oltre all'ID tabella.
Tutte le scritture in una vista autorizzata vengono applicate direttamente alla tabella di base.
Limitazioni della definizione delle visualizzazioni autorizzate
In una visualizzazione autorizzata, le righe o le colonne in cui puoi scrivere i dati sono limitate dalla definizione della visualizzazione autorizzata. In altre parole, puoi scrivere solo in righe e colonne che soddisfano gli stessi criteri specificati per la vista autorizzata.
Ad esempio, se la visualizzazione autorizzata è definita dal prefisso della chiave di riga
examplepetstore1
, non puoi scrivere dati utilizzando una chiave di riga di
examplepetstore2
; l'inizio del valore della chiave di riga deve includere l'intera
stringa examplepetstore1
.
Analogamente, 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 esterni alla vista autorizzata, ad esempio quando controlli la presenza di un valore in una richiesta di scrittura condizionale.
Per qualsiasi richiesta che scriva 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 subito replicata negli altri cluster dell'istanza.
Atomicità
Ogni richiesta MutateRows
inviata a un'istanza replicata viene eseguita come singola azione atomica sul cluster a cui viene indirizzata la richiesta. Quando la scrittura viene replicata agli altri cluster dell'istanza, anche questi cluster ricevono la scrittura come operazione atomica. I cluster non ricevono mutazioni parziali; una mutazione riesce o fallisce in modo atomico per tutte le celle che modifica.
Coerenza
Il tempo necessario per rendere disponibili per la lettura i dati che scrivi 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 utilizza la replica, Bigtable è coerente in modo asintotico. Puoi ottenere la coerenza read-your-writes 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 genere, crei un token di coerenza
dopo l'invio di un batch di scritture o dopo un determinato intervallo, ad esempio
un'ora. Poi puoi cedere il token a 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 verifica della coerenza può richiedere fino a qualche minuto la prima volta che lo utilizzi. Questo ritardo si verifica perché ogni cluster controlla tutti gli altri cluster per assicurarsi che non ci siano altri dati in arrivo. Dopo l'utilizzo iniziale o se aspetti diversi minuti per utilizzare il token 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 dalla quadrupla (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 la stessa quadrupletta esatta vengano inviate a due cluster diversi, Bigtable risolve automaticamente il conflitto utilizzando un algoritmo interno l'ultima scrittura è quella valida in base al tempo lato server. L'implementazione di Bigtable "l'ultima scrittura è quella valida" è deterministica e, quando la replica si aggiorna, tutti i cluster hanno lo stesso valore per la quadrupla.
Passaggi successivi
- Scopri di più sulla progettazione dello schema.
- Implementa i contatori utilizzando le celle aggregate.
- Utilizza l'emulatore Bigtable.