Datastore offre alta affidabilità, scalabilità e durabilità distribuendo i dati su più macchine e utilizzando la replica sincrona su un'ampia area geografica. Tuttavia, questo design presenta un compromesso: la velocità effettiva di scrittura per qualsiasi singolo gruppo di entità è limitata a circa un commit al secondo e sono presenti limitazioni per le query o le transazioni che interessano 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 coerenza elevata, soddisfacendo al contempo i requisiti di velocità effettiva di scrittura dell'applicazione.
Le letture a coerenza elevata restituiscono sempre i dati attuali e, se eseguite all'interno di una transazione, sembrano provenire da una singola istantanea coerente. Tuttavia, le query devono specificare un filtro di antenati per essere a coerenza elevata o partecipare a una transazione e le transazioni possono coinvolgere al massimo 25 gruppi di entità. Le letture a coerenza finale non presentano queste limitazioni e sono adeguate in molti casi. L'utilizzo di letture a coerenza finale può consentirti di distribuire i dati tra un numero maggiore di gruppi di entità, consentendoti di ottenere una maggiore velocità effettiva di scrittura eseguendo i commit in parallelo sui diversi gruppi di entità. Tuttavia, devi comprendere le caratteristiche delle letture a coerenza finale per determinare se sono adatte alla tua applicazione:
- I risultati di queste letture potrebbero non riflettere le transazioni più recenti. Ciò può verificarsi perché queste letture non garantiscono che la replica su cui vengono eseguite sia aggiornata. Utilizzano invece i dati disponibili sulla replica al momento dell'esecuzione della query. La latenza di replica è quasi sempre inferiore a pochi secondi.
- Una transazione di cui è stato eseguito il commit che interessava più entità potrebbe sembrare applicata ad alcune entità e non ad altre. Tieni presente, tuttavia, che una transazione non sembrerà mai essere stata applicata parzialmente all'interno di una singola entità.
- I risultati della query possono includere entità che non avrebbero dovuto essere incluse in base ai criteri di filtro e potrebbero escludere entità che avrebbero dovuto essere incluse. Ciò può verificarsi perché gli indici potrebbero essere letti in una versione diversa da quella in cui viene letta l'entità stessa.
Per capire come strutturare i dati per una elevata coerenza, confronta due approcci diversi per una semplice applicazione guestbook. Il primo approccio crea una nuova entità base per ogni entità creata:
Esegue quindi una query sul tipo di entità Greeting per i dieci saluti più recenti.
Tuttavia, poiché utilizzi una query non antenata, la replica utilizzata per eseguire la query in questo schema potrebbe non aver visto il nuovo saluto al momento dell'esecuzione della query. Tuttavia, quasi tutte le scritture saranno disponibili per le query non antenate entro pochi secondi dal commit. Per molte applicazioni, una soluzione che fornisce i risultati di una query non antenata nel contesto delle modifiche dell'utente corrente sarà in genere sufficiente a rendere completamente accettabili queste latenze di replica.
Se la elevata coerenza è importante per la tua applicazione, un approccio alternativo consiste nello scrivere entità con un percorso di antenati che identifichi la stessa entità base in tutte le entità che devono essere lette in una singola query di antenati a coerenza elevata:
Potrai quindi eseguire una query da predecessore a coerenza elevata all'interno del gruppo di entità identificato dall'entità base comune:
Questo approccio raggiunge una elevata coerenza scrivendo in un singolo gruppo di entità per guestbook, ma limita anche le modifiche al guestbook a non più di una scrittura al secondo (il limite supportato per i gruppi di entità). Se è probabile che la tua applicazione riscontri un utilizzo di scrittura più intenso, potresti dover prendere in considerazione l'utilizzo di altri mezzi: ad esempio, potresti inserire i post recenti in una memcache con una scadenza e visualizzare un mix di post recenti dalla memcache e da Datastore oppure memorizzarli nella cache in un cookie, inserire alcuni stati nell'URL o altro. L'obiettivo è trovare una soluzione di memorizzazione nella cache che fornisca i dati per l'utente corrente per il periodo di tempo in cui l'utente pubblica contenuti nella tua applicazione. Ricorda che, se esegui un'operazione get, una query di antenati o qualsiasi operazione all'interno di una transazione, vedrai sempre i dati scritti più di recente.