TrueTime è un orologio distribuito ad alta disponibilità che viene fornito su tutti i server Google1. TrueTime abilita per generare timestamp con aumento monotonico: un'applicazione può calcolano un timestamp T garantito maggiore di qualsiasi timestamp T" se "T" è stata completata prima della generazione di T. Questa garanzia è valida su tutti i server e su tutti i timestamp.
Questa funzionalità di TrueTime viene utilizzata da Spanner per assegnare i timestamp alle transazioni. Nello specifico, a ogni transazione viene assegnato un timestamp riflette l'istante in cui Spanner ritiene che abbia si è verificato un errore. Poiché Spanner utilizza il controllo della concorrenza multi-versione, la garanzia di ordinamento dei timestamp consente ai client di Spanner di eseguire letture coerenti in un intero database (anche in più regioni Cloud) senza bloccare le scritture.
Coerenza esterna
Spanner offre ai clienti le garanzie più rigorose per il controllo della concorrenza per le transazioni, ovvero la coerenza esterna2. In caso di coerenza esterna, il sistema si comporta come se tutte le transazioni fossero state eseguite in sequenza, anche se Spanner le esegue su più server (e possibilmente in più data center) per prestazioni e disponibilità superiori. Inoltre, se uno viene completata prima che venga avviata un'altra transazione, il sistema garantisce che i clienti non vedano mai uno stato che include l'effetto del la seconda transazione, ma non la prima. Intuitivamente, Spanner non è distinguibile a livello semantico da un database di una singola macchina. Anche se offre garanzie così elevate, Spanner consente alle applicazioni di raggiungere prestazioni paragonabili a quelle dei database che offrono garanzie meno stringenti (in cambio di prestazioni più elevate). Ad esempio, come i database che supportano snapshot di isolamento, Spanner consente alle scritture di procedere senza essere bloccate transazioni di sola lettura, ma senza presentare le anomalie rilevate l'isolamento lo consente.
La coerenza esterna semplifica notevolmente lo sviluppo delle applicazioni. Ad esempio, supponiamo che tu abbia creato un'applicazione bancaria su Spanner e che uno dei tuoi clienti abbia inizialmente 50 $ sul conto corrente e 50 $ sul conto risparmio. L'applicazione avvia quindi un flusso di lavoro in cui prima committa una transazione T1 per depositare 200 $ nell'account di risparmio, poi emette una seconda transazione T2 per addebitare 150 $ dall'account corrente. Inoltre, supponiamo che, alla fine della giornata, i saldi negativi in un account sono coperte automaticamente da altri account e un cliente comporta una sanzione se il saldo totale di tutti i loro account è negativo in qualsiasi momento durante la giornata. La coerenza esterna garantisce che, poiché T2 inizia a eseguire il commit dopo la fine di T1, tutti i lettori del database osserveranno che il deposito T1 si è verificato prima dell'addebito T2. In altre parole, la coerenza esterna garantisce che nessuna si vedrà uno stato in cui T2 si verifica prima di T1; nel In altre parole, al debito non sarà mai applicata una penale per insufficienza di fondi.
Un database tradizionale che utilizza uno spazio di archiviazione a versione singola e un sistema di archiviazione a due fasi rigoroso il blocco fornisce coerenza esterna. Purtroppo, in un sistema di questo tipo, ogni volta che l'applicazione desidera leggere i dati più aggiornati (ovvero "lettura elevata"), il sistema acquisisce un blocco di lettura sui dati, che blocca le scritture ai dati che vengono letti.
Timestamp e controllo della contemporaneità multiversione (MVCC)
Per leggere senza bloccare le scritture, Spanner e molti altri sistemi di database mantenere più versioni immutabili dei dati (spesso definita contemporaneità multiversione . Una scrittura crea una nuova versione immutabile il cui timestamp è quello della transazione di scrittura. Una "lettura istantanea" a un timestamp restituisce il valore alla versione più recente precedente a quel timestamp e non deve bloccare scrive. È quindi importante che i timestamp assegnati alle versioni siano coerenti con l'ordine in cui è possibile osservare l'commit delle transazioni. Chiamiamo questa proprietà "timbratura corretta". Tieni presente che l'esistenza di una timbratura corretta è equivalente alla coerenza esterna.
Per capire perché l'apposizione di un timestamp corretto è importante, prendi in considerazione l'esempio bancario della sezione precedente. Senza un timestamp corretto, a T2 potrebbe essere assegnato un timestamp precedente a quello assegnato a T1 (ad esempio, se un sistema ipotetico utilizzava orologi locali anziché TrueTime e l'orologio del server che elabora T2 aveva un ritardo minimo). Un'istantanea letta potrebbe quindi riflettere l'addebito del T2, ma non il bonifico T1, anche se il cliente ha visto la sua fine prima di iniziare l'addebito.
Ottenere timestamp corretti è banale per un database di una singola macchina (ad esempio, puoi semplicemente assegnare i timestamp da un contatore globale in aumento monotonico). Raggiungere questo obiettivo in un sistema ampiamente distribuito come Spanner, in cui i server di tutto il mondo devono assegnare i timestamp, è molto più difficile da fare in modo efficiente.
Spanner si basa su TrueTime per generare timestamp in aumento monotonico. Spanner utilizza questi timestamp in due modi. Innanzitutto, li utilizza come timestamp appropriati per le transazioni di scrittura senza la necessità di una comunicazione globale. In secondo luogo, li utilizza come timestamp per le letture sicure, il che consente di eseguire le letture sicure in un unico ciclo di comunicazione, anche quelle che interessano più server.
Domande frequenti
Quali garanzie di coerenza offre Spanner?
Spanner fornisce coerenza esterna, ovvero la coerenza più rigorosa per i sistemi di elaborazione delle transazioni. Tutte le transazioni in Spannersoddisfano questa proprietà di coerenza, non solo quelle all'interno di una partizione. La coerenza esterna afferma che Spanner esegue le transazioni in modo indistinguibile da un sistema in cui le transazioni vengono eseguite in sequenza e, inoltre, che l'ordine seriale è coerente con l'ordine in cui è possibile osservare l'commit delle transazioni. Poiché i timestamp generati per le transazioni corrispondono all'ordine seriale, se un client vede l'inizio dell'commit di una transazione T2 dopo il completamento di un'altra transazione T1, il sistema assegna a T2 un timestamp superiore a quello di T1.
Spanner offre linearizzabilità?
Sì. Infatti, Spanner fornisce coerenza esterna, che è una maggiore rispetto alla linearità, perché la linearizzabilità non dice nulla sul comportamento delle transazioni. La linearizzabilità è una proprietà degli oggetti concorrenziali che supportano operazioni di lettura e scrittura atomiche. In un database, "object" formato da una singola riga o anche da una singola cella. Esterni la coerenza è una proprietà dei sistemi di elaborazione delle transazioni, sintetizzare dinamicamente le transazioni che contengono più su oggetti arbitrari. La linearizzabilità può essere vista come un caso speciale di coerenza esterna, dove una transazione può contenere solo una singola lettura di scrittura su un singolo oggetto.
Spanner fornisce la serializzazione?
Sì. Infatti, Spanner fornisce coerenza esterna, che è una procedura più restrittiva che la serializzabilità. Un sistema di elaborazione delle transazioni è serializzabile se esegue le transazioni in modo indistinguibile da un sistema in cui le transazioni vengono eseguite in sequenza. Spanner garantisce inoltre che l'ordine seriale sia coerente con l'ordine in cui le transazioni possono da osservare per impegnarsi.
Considera di nuovo l'esempio bancario utilizzato in precedenza. In un sistema che offre la serializzabilità, ma non la coerenza esterna, anche se il cliente ha eseguito T1 e poi T2 in sequenza, il sistema potrebbe riordinarli, il che potrebbe comportare l'applicazione di una penale sul debito a causa di fondi insufficienti.
Spanner offre elevata coerenza?
Sì. Infatti, Spanner fornisce coerenza esterna, che è una proprietà più forte dell'elevata coerenza. La modalità predefinita per le letture in Spanner è "strong", che garantisce il rispetto degli effetti di tutte le transazioni di cui è stato eseguito il commit prima dell'inizio dell'operazione, indipendentemente dalla replica riceve la lettura.
Qual è la differenza tra elevata coerenza e coerenza esterna?
Un protocollo di replica mostra "elevata coerenza" se gli oggetti replicati sono linearizzabili. Come la linearizzabilità, la "coerenza forte" è meno efficace della "coerenza esterna", perché non dice nulla sul comportamento delle transazioni.
Spanner fornisce coerenza finale (o lazy)?
Spanner fornisce coerenza esterna, che è una proprietà molto più efficace rispetto alla coerenza finale. La coerenza finale negozia garanzie più deboli per con prestazioni più elevate. La coerenza eventuale è problematica perché significa che i lettori possono osservare il database in uno stato in cui non è mai stato effettivamente (ad es. una lettura potrebbe osservare uno stato in cui la transazione B è stata eseguita, ma non la transazione A, anche se A è avvenuta prima di B). Spanner offre letture non aggiornate, che offrono vantaggi simili in termini di prestazioni rispetto alla coerenza finale, ma con garanzie di coerenza molto più elevate. Una lettura inattiva restituisce i dati di una timestamp, che non può le scritture di blocco poiché le versioni precedenti dei dati sono immutabili.