Strutturazione dei dati per una coerenza elevata

Datastore offre alta disponibilità, scalabilità e durabilità distribuendo i dati su molti computer e utilizzando la replica sincrona su un'ampia area geografica. Tuttavia, c'è un compromesso progettazione, ovvero la velocità effettiva di scrittura per ogni gruppo di entità è limitato a circa un commit al secondo ed esistono limitazioni per le query o le transazioni che in più gruppi di entità. Questa pagina descrive queste limitazioni in modo più dettagliato e illustra le best practice per strutturare i dati in modo da supportare una consistenza rigorosa, soddisfacendo al contempo i requisiti di throughput in scrittura dell'applicazione.

Le letture altamente coerenti restituiscono sempre i dati correnti e, se eseguite all'interno di un di transazioni, sembreranno provenire da un'unica istantanea coerente. Tuttavia, Le query devono specificare un filtro predecessore per essere partecipano a una transazione e le transazioni possono riguardare al massimo 25 persone giuridiche gruppi. Le letture coerenti alla fine non hanno queste limitazioni e sono adeguato in molti casi. L'utilizzo delle letture eventualmente coerenti può consentire di distribuire i dati tra un numero maggiore di gruppi di entità, in modo da ottenere un throughput di scrittura maggiore eseguendo i commit in parallelo sui diversi gruppi di entità. Ma è necessario comprendere le caratteristiche letture coerenti per determinare se sono adatte la tua applicazione:

  • I risultati di queste letture potrebbero non riflettere le ultime transazioni. Questo perché queste letture non assicurano che la replica sia in esecuzione su sia aggiornato. Utilizzano invece qualsiasi dato disponibile su quella replica al momento dell'esecuzione della query. La latenza di replica è quasi sempre inferiore a per alcuni secondi.
  • Una transazione impegnata che ha interessato più entità potrebbe sembrare essere stata applicata solo ad alcune entità e non ad altre. Tieni presente, tuttavia, che transazione non risulterà mai applicata parzialmente all'interno di un singolo dell'oggetto.
  • I risultati della query possono includere entità che non dovevano essere incluse in base ai criteri di filtro ed escludere entità che dovevano essere incluse. Questo può accadere perché gli indici potrebbero essere letti a un più elevata rispetto alla lettura dell'entità stessa.

Per capire come strutturare i dati per una coerenza elevata, confronta due approcci diversi per una semplice applicazione guestbook. Il primo approccio crea una nuova entità principale per ogni entità creata:

g := Greeting{ /* ... */ }
key := datastore.NewIncompleteKey(ctx, "Greeting", nil)

Quindi esegue una query sul tipo di entità Greeting per conoscere i dieci saluti più recenti.

q := datastore.NewQuery("Greeting").Order("-Date").Limit(10)

Tuttavia, poiché utilizzi una query non relativa all'antenato, la replica utilizzata per eseguire la query in questo schema potrebbe non aver visto il nuovo saluto al momento dell'esecuzione della query. Ciononostante, quasi tutte le scritture saranno disponibili non predecessori entro pochi secondi dal commit. Per molte applicazioni, in genere è sufficiente una soluzione che fornisca i risultati di una query non principale nel contesto delle modifiche dell'utente corrente per rendere completamente accettabili queste latenze di replica.

Se per la tua applicazione è importante l'elevata coerenza, puoi adottare un approccio alternativo scrivere entità con un percorso predecessore che identifica la stessa entità base tra tutte le entità che devono essere lette in un singolo predecessore a elevata coerenza query:

g := Greeting{ /* ... */ }
key := datastore.NewIncompleteKey(ctx, "Greeting", guestbookKey(ctx))

Potrai quindi eseguire una query sull'antenato fortemente coerente all'interno del gruppo di entità identificato dall'entità radice comune:

q := datastore.NewQuery("Greeting").Ancestor(guestbookKey(ctx)).Order("-Date").Limit(10)

Questo approccio garantisce elevata coerenza scrivendo a un singolo gruppo di entità per libro degli ospiti, ma limita anche le modifiche al libro degli ospiti a un 1 scrittura al secondo (il limite supportato per i gruppi di entità). Se la tua applicazione è probabile che riscontri un utilizzo più elevato delle scritture, potresti dover prendere in considerazione l'utilizzo di altri mezzi: ad esempio, potresti inserire i post recenti in un memcache con una scadenza e mostrare un mix di post recenti da memcache e Datastore oppure memorizzarli nella cache in un cookie, inserire un po' di stato nell'URL o qualcos'altro. L'obiettivo è trovare una soluzione di memorizzazione nella cache che fornisca i dati dell'utente corrente per il periodo di tempo in cui l'utente pubblica nella tua applicazione. Ricorda che se esegui un comando GET, una query sull'antenato o qualsiasi operazione all'interno di una transazione, vedrai sempre i dati scritti più di recente.