
quindi sì, oggi ne parlerò
contesto e alcune specifiche pratiche
su come costruiamo una consistenza più forte
garanzie nel nostro valore chiave esistente
negozio su Twitter
il mio nome è Baz I am on the core storage
squadra su Twitter siamo una delle squadre
che fornisce come servizio gestito
deposito per gli ingegneri dell’azienda
chi costruirà le loro applicazioni lo farò
darti un secondo per seguirmi
Twitter uno dei modi in cui lo facciamo
e lo stanno facendo da un po ‘ora
è con un database che chiamiamo
Manhattan è la nostra distribuzione
archivio di valori-chiave è la chiave primaria
valore negozio Twitter che abbiamo costruito da
il ground up circa quattro anni fa
Manhattan non esisteva e oggi è così
il negozio canonico per un sacco di molto
dati importanti alle cose dell’azienda
come tweets Dati dell’inserzionista DMS e a
intera lunga coda di altre applicazioni
Ti darò un po ‘di contesto per la
database tra le altre ragioni uno dei
le cose per cui abbiamo costruito Manhattan erano
essere molto facile da adottare per gli sviluppatori
stoccaggio e entrare rapidamente in produzione
con i loro servizi al fine di farlo
abbiamo sottolineato alcune cose che forniamo
accesso self-service al database
attraverso un’interfaccia web cerchiamo di nasconderci
come molte complessità di infrastruttura come
possiamo dai nostri clienti l’altro
ingegneri su Twitter cose come fare
replica globale trasparente attraverso
tutte le regioni dei nostri data center
permettiamo ai clienti di condividere lo spazio
grandi cluster questo riduce il
tempo di provisioning quando chiedi ascia
stoccaggio e riduce il carico sul
sviluppatori da dover impostare e
gestire nuovi cluster ogni volta che qualcuno ha
un nuovo caso d’uso e ne forniamo anche alcuni
nifty visibilità automatica e
osservabilità e allerta in modo che
le persone hanno visibilità su come loro
tu
utilizzando il database ora come con qualsiasi
servizio di successo in quanto ottiene di più
popolare e ottiene più persone che adottano
abituarsi a usarlo e loro vogliono
iniziare a usarlo per casi d’ uso per i quali
non era esattamente progettato nel nostro caso
ciò potrebbe significare che qualcuno che era
usando questa chiave alla fine coerente
value store vuole iniziare a usarlo per
parti dei loro dati che necessitano di maggiore
garanzie di consistenza quando provano a
fai questo e loro non possono con il nostro sistema
causa molto dolore significa questo
devono fare dei compromessi che loro
non vogliono fare o che non sono
felice con e entrambi fanno quelli
compromessi attraverso l’utilizzo del nostro sistema o
attraverso l’ utilizzo di un sistema diverso come in
il nostro DBMS che non fornisce alcuni di
le garanzie che ti forniamo così
un ingegnere il cui compito è risolvere
questi problemi per i tuoi clienti sono
presentato con una scelta una scelta che noi
vedi un sacco di cose che fai costruisci una nuova
servizio o utilizzare un nuovo servizio esistente
accanto in parallelo al al
servizio che devi già risolvere
questi problemi o ne crei di nuovi
funzionalità nel servizio esistente oggi
Ora questa è una scala e non ho bisogno di
ti dico che non vuoi essere presente
il lato più lontano della scala in cui tu
costruire un software gonfiato che non è molto
bravo in qualsiasi cosa ma anche quando lo sei
costruire infrastrutture non sempre
voglio creare servizi che sono anche troppo
specifico e ci sono alcuni motivi per
quello sta facendo funzionare più sistemi dentro
la produzione può essere davvero dolorosa ogni
il sistema avrà un altro
profilo operativo ogni sistema è
andando ad avere i suoi piccoli capricci e
sarà doloroso per il tuo
ingegneri di guardia per conoscere ogni sistema
in profondità un altro è quello per
infrastrutture complesse un sacco di cose
stanno per essere comune tra questi
servizi per un database per esempio
hai sempre bisogno di gestire
i tuoi nodi di cui avrai sempre bisogno
per spostare i dati in giro e si sta andando a
devi ricostruire questi componenti
per il
sistemi o cercare di astrarre continuamente
componenti fuori dai vostri sistemi che possono
hanno rendimenti decrescenti e probabilmente
la più grande ragione che non vuoi
molti sistemi separati sono io
ti garantisco che i tuoi clienti no
voglio parlare con cinque diversi database
con cinque diverse API ciascuna
fornisce una garanzia leggermente diversa
o funzione così in realtà vuoi essere
da qualche parte qui sulla scala in cui sei
costruire sistemi specializzati che sono
bravi in quello che fanno ma possono evolversi
in modo logico e riflessivo per
fornire più funzionalità al tuo
i clienti quindi è quello che volevamo fare
per risolvere questo problema per i nostri clienti
e gli ingegneri su Twitter e in
per parlare di come l’abbiamo fatto lo farò
diamo a voi ragazzi una panoramica del
architettura architettonica del nostro
alla fine database coerente sarò
andare piuttosto rapidamente per un sacco di generale
concetti se si ha familiarità con
sistemi distribuiti o distribuiti
database molto di questo andrà a cercare
molto familiare ma se non si sente libero di farlo
fare domande dopo il discorso o trovarmi
alla conferenza come un buon posto per
iniziare come qualsiasi con il database è con
il modello di dati Manhattan, come ho detto, è a
negozio di valore chiave e abbiamo diviso le nostre chiavi
in due componenti una chiave di partizione o P
chiave e una chiave locale o L chiave locale
sono memorizzati insieme sulla stessa macchina
sotto la chiave di partizione che hanno
località che è il motivo per cui noi li chiamiamo
e questo significa che puoi farlo
Interrogazione a lato dell’intervallo interessante per
istanza in questo set di dati se il tasto p
è un ID utente puoi dire qualcosa di simile
prendi tutte le chiavi che iniziano con
il profilo di parole per questo particolare
utente e otterresti l’utente
Profilo Questo dovrebbe essere familiare a voi
se hai usato Cassandra o BigTable come
uno schema a righe e colonne o se lo hai
dynamodb utilizzato come chiave hash e intervallo
chiave così prendiamo queste chiavi e noi
distribuirli attorno al cluster
il modo in cui lo facciamo è l’hashing
partizione e chiave
in modo casuale in un frammento e poi
replicando quei frammenti e
distribuendoli ai nodi nel
cluster quando vuoi fare una richiesta
si invia un client invia la loro richiesta a
uno dei tanti apolidi simmetrici
i nodi coordinatori prendono i nodi
richiesta prendere la chiave da esso trovare il
shard che quella chiave appartiene a trovare il
nodi di archiviazione su cui vive la shard
e quindi inoltra tali richieste in
parallelo a tutti quei nodi di archiviazione
in attesa di una risposta tale risposta
potrebbe essere un successo se è giusto
potrebbe essere l’ ultimo valore se si tratta di una lettura
ora quando dico che il coordinatore
i nodi inoltrano questi dati in parallelo a
tutti questi nodi di archiviazione che dovrebbero
essere un regalo immediatamente che sono
parlando di un quorum basato alla fine
sistema coerente specificamente in questo
caso usiamo stile Dinamo eventuale
coerenza come nella Dinamo amazzonica
carta e abbiamo l’ultima destra vince
risoluzione dei conflitti facendo ciò che possiamo
inoltrare le richieste in parallelo a tutti
degli ospiti e quelle richieste possono
riuscire e fallire indipendentemente da ciascuno
altro senza necessariamente influenzare il
successo complessivo dell’intera richiesta
e finché si fanno richieste
a un quorum di host se questo è importante
a te in questo caso che sarebbero due
su tre e quelle richieste hanno successo
sei sicuro di essere sicuro
livelli di coerenza come leggi il tuo
diritti in questo caso quindi se questi sono
diritti sul database e uno di essi
fallisce a causa di una partizione di rete o
a causa di un riavvio a rotazione e
successivamente fai una lettura da a
database e in tutta la lettura anche
ha successo anche contro un quorum di host
se uno di questi host ha fallito in precedenza
sei sicuro di vederne almeno uno
versione dei dati che è l’ultima
versione che hai scritto e di
Certo che non possiamo chiamarlo in modo definitivo
coerenza se non lo facciamo alla fine
i dati coerenti tra gli host così noi
avere un processo anti entropia che funziona
sullo sfondo chiamato replica
riconciliazione
questo va e confronta i frammenti attraverso
ogni replica assicurandosi che abbiano
gli stessi dati e se non lo fanno
copia quei dati, quindi questi sono tutti
alcuni semplici standard
concetti perché dovremmo scegliere di costruire un
sistema in questo modo
Il vantaggio principale che si ottiene da
costruire un sistema come questo è super
alta disponibilità perché tutto il
nodi di archiviazione sono uguali tra loro che
non abbiamo una relazione di padronanza noi
non hanno latenza e disponibilità
singhiozzo da cose come il failover e
master rielezione e perché abbiamo scelto
per inviare la richiesta in parallelo a tutti
di questi host questa è una latenza
trade-off del throughput sei essenzialmente
in attesa di una migliore risposta di n da
queste repliche e stai ottenendo il
migliore latenza possibile del sistema
può fornire in qualsiasi momento e si ottiene anche
semplicità e semplicità è dentro
scambio per forse un po ‘meno di
modello di coerenza intuitivo che ottieni per ultimo
vince il diritto o davvero con qualsiasi tipo di
risoluzione del conflitto hands-off un modo per
spostare in modo trasparente i dati in modo asincrono
replicare i dati da un set di host a
un altro e avere questi dati senza soluzione di continuità
integrato nei dati esistenti nel
sistema quindi se copio i dati tramite
riconciliazione delle repliche o se io
replicare i dati da un altro
regione che combina solo con i dati
che è già sul sistema in modo
ciò rende la nostra replica incrociata
storia molto bella molto facile per le persone
usa e non devi pensarci
come funzionano i miei dati cross-region
il database ma come ho detto per alcuni
la gente non è abbastanza quando è
non abbastanza un caso d’uso è molto simile a
qualsiasi altro tipo di programmazione concorrente
quando hai bisogno di unicità o controllo e
imposta il vincolo di fronte a concorrenti
aggiornamenti al database quindi un esempio di
che potrebbe essere se due utenti stanno provando a
entrambi riservano un nome utente
non solo ho bisogno solo di uno di questi
gli utenti alla fine riescono a prenotare
questo nome utente non posso avere gare che
risultato in entrambi pensando questo
sono riusciti a riservare il nome utente
perché questo può rompere il business
logica della tua domanda quindi per
istanza se entrambi questi utenti ci hanno provato
Riserva
entrambi hanno visto che il nome utente era gratuito
entrambi hanno detto di assegnarmelo, se solo lo fosse
se entrambi hanno avuto successo su questo
incarico ma solo la seconda persona
chi è successo a fare quella richiesta
è riuscito questo è un comportamento molto imbarazzante
per la tua applicazione da superare
e si applica anche attraverso le regioni
a livello globale così due persone potrebbero provare
per prenotare un nome utente di cui uno è in
Uno di loro a Chicago è addirittura a Nairobi
se stanno parlando con dati diversi
centri dovrebbero ancora ottenere questi stessi
garanzie e nello stesso esempio tu
voglio un’altra cosa che è un de Missa
T dei tuoi aggiornamenti se invio un aggiornamento a
il database per prenotare questo nome utente in
In caso di fallimento, voglio che fallisca
ovunque nel caso del successo che voglio
per riuscire ovunque non riesco a ottenere
in uno stato in un fallimento Canario dove
una minoranza di ospiti pensa che a
il nome utente è riservato e non posso
garantire una lettura prevedibile quando vado
torna indietro e prova a vedere chi ha questo
nome utente questo è uno stato che puoi
entrare con la coerenza finale e
questo stato sarà risolto sia in
una direzione o l’altra a seconda di
se questo host esistente muore o meno
quindi è inaccettabile per alcuni casi d’uso
quindi ora sappiamo che abbiamo questo tipo di
genuino bisogno di una maggiore coerenza
modella come adattiamo la nostra corrente
architettura per supportare questo
possiamo aggiungere un nuovo componente al nostro
percorso di richiesta che è log in particolare
log distribuiti sequenziali replicati
nella forma per noi di Twitter
registro distribuito che è di recente aperto
libreria di log di origine creata in cima a a
contabile irregolare lo scopo di a
log sequenziale è quello di tutti
aggiornamenti che entrano in questo sistema in
questo registro può essere letto nello stesso modo
ordine da tutti i consumatori in uscita
diventa complicato quando si replica
questo registro per la durata e voi
distribuire questo registro per resilienza e
scalabilità e il registro deve fare i conti
concetti come consenso o padronanza
con failover e scherma e deve
ottenere tutti questi concetti complicati giusti
ora questo tipo di componente sta diventando
sempre più popolare in molti
diversi tipi di infrastrutture se tu
erano all’ultimo discorso qui poi hai visto
Kafka che è un tipo di distribuito
registro e quindi non parlerò di come questi
i log sono implementati ma parlerò
su come usiamo questo registro quali sono alcuni
delle complessità dell’interazione quando
introduciamo questo nuovo tipo di componente
nel nostro percorso di richiesta e avere questo nuovo
tipo di modello di coerenza, così ho detto
prima che tutte le chiavi siano
partizionato in frammenti questo frammento è
questa unità granulare finale di
partizionamento e distribuzione nel
sistema in modo da poter spostare i frammenti in
tra gli host quello che posso scegliere di fare è
Dì che tutte le operazioni che stanno andando
per aggiornare o agire su un frammento devono andare
attraverso un registro e posso fare questo registro
per infrastruttura di shard e quindi posso
avere tutti i nodi di archiviazione che possedevano
questo frammento consuma tutti i loro aggiornamenti
per quella scheggia dal registro e
avere questa garanzia che tutti quelli
gli aggiornamenti saranno garantiti
consegnato e consegnato in ordine da
il log e ora una volta che ho questo posso
fare queste operazioni praticamente ogni
tutto ciò che voglio che siano lì
può essere letto o scritto così com’erano
prima o posso iniziare a inviare il confronto
e impostare le operazioni che posso iniziare a inviare
operazioni di incremento posso inviare qualsiasi tipo
di funzionamento che è basato deterministico
sui dati che arrivano nel
operazione stessa e il dato che
esiste già nel database che è
garantito per essere lo stesso su ogni
nodo di archiviazione nel momento in cui quello
operazione viene elaborata in modo che possiamo già
vediamo che introducendo questo possiamo
risolvere alcuni dei problemi che eravamo
preoccupato prima di prendere il
esempio di prenotazione Posso modellare a
prenotazione di un nome utente come check-in
imposta operazione in cui dico se un nome utente
è gratuito assegnare il mio ID utente a quello
nome utente e due utenti che lo sono
fare contemporaneamente questa richiesta
appare in questo registro in un ordine che
l’ordine non ha importanza perché
lo stanno facendo contemporaneamente e sia
l’ordine è valido ma ciò che è importante è
che tutti i nodi di archiviazione di tutto il
le repliche che elaborano questa richiesta vedono
lo stesso ordine, quindi cosa finirà
accadendo è quello il primo che
entra nel registro sarà in grado di prenotare
quel nome utente e il secondo lo farà
fallire la sua condizione di controllo e non prenotare
il nome utente e vedere una felice applicazione
livello di errore questo tipo di semplice cambiamento
al modello di messaggistica consente il nostro
garanzie da rafforzare abbastanza a
un po ‘, quindi rimpiccioliamo un po ‘ e
vedere come questo si inserisce nel più grande
architettura ora quando un cliente invia un
richiesta a un coordinatore invece di
inoltrare tale richiesta direttamente al
nodi di archiviazione in avanti del coordinatore
per il log che possiede il frammento per
su quale chiave vive e poi su
nodi di archiviazione
consumare da quel registro riprodurre
operazione e rispondere con ancora il
successo se è giusto il valore se
è una lettura o qualunque sia il risultato
è del tuo complesso più complesso
operazione di nuovo al coordinatore
ora se noti che ho una nuova garanzia
qui che non avevo prima che sia
che se il diritto entra nel registro lo so
quello che vedranno i nodi di archiviazione
e se un nodo di archiviazione elabora un
operazione so che tutti gli altri
nodi di archiviazione che lo elaborano
l’operazione restituirà la stessa risposta
perché hanno gli stessi dati quindi ora io
può iniziare a fare cose più interessanti
con il mio modello di richiesta in modo da poter mantenere
le stesse garanzie che voglio avere
riducendo la latenza sul client
lato per ogni richiesta data così per
esempio diciamo che lo so per certo
tutti i miei diritti e tutte le mie letture
un mio set di dati andrà
attraverso questo log sequenziale bene ora
posso dire se sto inviando una scrittura al più presto
come quella scrittura entra nel registro ho finito io
sappi che quella scrittura sarà alla fine
essere applicato ai nodi di archiviazione così io
solo bisogno di aspettare che il registro agisca
che ha questo diritto duraturo prima di me
può restituire un successo al cliente
e so che ogni successiva lettura lo farà
essere citato dietro quella scrittura nel registro
quindi vedrà la scrittura come io
aspettati e quando invio quella lettura
o se invio un messaggio più complesso
operazione che ha bisogno di un risultato solo io
è necessario attendere per uno degli archivi
nodi per rispondere perché so tutto
gli altri nodi di archiviazione risponderanno
con gli stessi dati quindi questo lo rende sicuro
tipi di operazioni forti accadono a
un po ‘più veloce possiamo aspettare
per la risposta del registro o il più veloce
risposta da un host ma posso ancora fare
qualcosa di interessante posso dire di esserlo
in attesa di un quorum di risposte prima
non sarebbe il mio modello alla fine coerente
Come
ma aspetto un quorum di risposte ora
quindi se invio un diritto o se invio un cast
o un incremento o qualcosa che aspetterò
per un quorum di risposte a tornare
e se lo faccio lo so
richiesta è durevole e coerente sul
note di archiviazione stesse e quando invio
una lettura successiva perché non l’ho fatto
cambia il mio percorso di richiesta Ho solo aggiunto un
nuova opzione per la richiesta può contenere
questo database posso inviare una lettura
il normale fan-out alla fine coerente
percorso e quando lo faccio ottengo tutto il
benefici che stavo ricevendo prima
una richiesta alla fine coerente alta
disponibilità bassa latenza senza mangiare
qualsiasi costo di passare attraverso il registro
ma continuo a fare aggiornamenti in questo
moda più fortemente coerente così questo
è un modello interessante e in a
poche parole questo è il modo possiamo aggiungere questo registro
componente nel database da aggiungere
consistenza più forte quindi vediamo cosa
sono i risultati che ne derivano
bene prima abbiamo guadagnato quello che è
stavamo cercando di guadagnare perché gli aggiornamenti
sono ordinati per frammento e le chiavi sono
hash a caso in frammenti ma
coerentemente in frammenti noi efficacemente
acquisito in ordine di aggiornamenti su una chiave
base linearizza l’abilità per le nostre chiavi
tecnicamente abbiamo per gli aggiornamenti per
tutto nel frammento ma perché tu
come utente non so per certo se due
le chiavi finiranno nello stesso shard tu
non fare affidamento su ciò è importante
per notare che non abbiamo pieno
transazioni distribuite tra i frammenti
questo è un problema più complesso ed è
qualcosa su cui dovrebbe essere costruito
cima a questo sistema più di base anche noi
abbiamo o possiamo dire che abbiamo mantenuto il fallimento
isolamento a livello di shard perché tutto
dei nostri diritti passano attraverso i log che sono
posseduto da frammenti se abbiamo un singhiozzo o
un problema o un problema con un individuo
ceppo
quel problema è limitato a molto
piccolo frammento dello spazio chiave che
appartiene a quel frammento e anche perché
abbiamo solo aggiunto questo nuovo percorso nel nostro
architettura invece di sostituirla
completamente abbiamo questa capacità di fare a
coppia cose non solo possiamo mescolare forte
e infine set di dati coerenti
all’interno dello stesso cluster possiamo effettivamente
in una certa misura mescolare forte ed eventualmente
richieste coerenti all’interno degli stessi dati
set e questo è ciò che intendo quando dico
che stiamo fornendo flessibile
livelli di consistenza che un utente può tornare indietro
e avanti attraverso questo continuum in mezzo
super alta disponibilità e carina
forte per oggetto linearizza l’abilità di
basta modificare il tipo di richiesta
fare su una base per richiesta al
database e questo è davvero potente per
i nostri clienti e ti permette di ottenere
esattamente quello che volevi nel sistema
esattamente il tempo che vuoi
Certo, abbiamo prima fatto dei compromessi
il trade-off è ovvio che abbiamo aggiunto
un nuovo componente non è il nostro
componente particolarmente semplice in
percorso di richiesta e così in media siamo
aggiungerò un po ‘ di latenza nel
centro dati locale che potrebbe essere pochi
millisecondi di latenza, se lo sei
parlando di fare coordinamento attraverso
regioni che sono vincolate dal
Deludentemente bassa velocità della luce e
quindi avrai un ordine
magnitudine più latenza aggiunta al tuo
richieste che devono coordinarsi lontano
in tutto il mondo abbiamo anche tutto il resto
abbiamo provato a isolare i guasti esposti
noi stessi a questa cosa che eravamo
cercando di evitare quale è il singhiozzo di latenza
quindi quando ci sono alcuni tipi di problemi
o rielezioni su un singolo registro
che rallentano gli aggiornamenti per un
il frammento individuale in cui un cliente vedrà
le loro alte agenzie percentuali
aumentare e va bene per te
questo ha un compromesso che devi essere
va bene come sviluppatore di applicazioni
e infine uno interessante
perché abbiamo detto che tutti questi
gli aggiornamenti devono avvenire in ordine e loro
devono essere applicati per mantenere
l’integrità del database e il
dati sul database allora abbiamo il
situazione in cui, se per qualche motivo
le repliche non possono applicare un’operazione che
legge da un flusso da un registro il
l’unica opzione che abbiamo è
interrompere completamente le operazioni per quel registro
quindi perché, perché non potremmo essere in grado di applicare
un’operazione normalmente dovrebbe essere tutto
applicare ma operando a noi scala
prendere in considerazione che lì
potrebbero essere bug che dobbiamo prendere in
conto che potrebbe esserci qualche tipo di
problema di corruzione eccezionale e quello
le singole repliche ora non possono continuare
per elaborare le operazioni da quel registro e
abbiamo una indisponibilità formale questo può
essere spaventoso certamente suona spaventoso ed è
dove cose come eccellente
osservabilità allerta eccellente
entrano in gioco strumenti eccellenti da realizzare
sicuro che se questo accade perché tu
dobbiamo rendere conto di tutte le possibilità che noi
conoscilo subito e risolviamo
il più rapidamente possibile, ecco cosa
sembra quando aggiungiamo questo nuovo percorso
ed è importante ora che lo hai
pensa a come è questo nuovo modello
che abbiamo aggiunto diverso dal
modello esistente e come lo usiamo
nuovo modello e gestire i nostri cluster con
questo nuovo modello in un modo che non lo è
speciale o unico che funziona solo con
il sistema che avevamo già così
per noi e per i nostri clienti stiamo aggiungendo
qualcosa senza perdere troppo
quando penso a come questo evento questo
è alla fine coerente e questo
modello fortemente coerente sono diversi
la prima cosa che mi viene in mente
è dove l’autorità dei tuoi dati
viene dallo stile della dinamo
modello alla fine coerente
l’autorità dei tuoi dati è consegnata
insieme ai tuoi valori nella forma di a
versione o timestamp questa versione
l’informazione è ciò che viene applicato al
back – end e decide se i nuovi dati possono
sovrascrivi i vecchi dati quindi in questo esempio
abbiamo valori abbiamo una chiave con valore
X alla versione 1 già su queste note
e una nuova chiave è l’aggiornamento di quella chiave
sta arrivando con il valore Y alla versione 2
e l’ unica ragione per la ragione
l’aggiornamento è accettato è perché il
la versione è più recente è interessante
perché disaccoppia efficacemente il
autorità dei dati dall’ordine in
che i dati arrivano è ciò che dà
noi che la risoluzione del conflitto è perché
della risoluzione del conflitto è cosa
ci dà le belle proprietà che noi
ottenuto prima è quello che ci dà il
idempotenza degli aggiornamenti che entrano in
il database ma è interessante
motivo anche per i benefici che
fornisce il nuovo modello è completamente
è diverso l’ordine degli aggiornamenti
tutto ciò che conta per i dati nel
back end e se voglio mantenere
attorno ad alcune informazioni sulla versione di me
devono mantenere che indipendentemente
ogni singolo host e se lo voglio
le informazioni sulla versione sono le stesse su a
attraverso gli host che è qualcosa che
Voglio se voglio ancora poterlo fare
rendere quelli stile alla fine coerente
richieste di quorum, quindi devo farlo
come un dettaglio di implementazione di come io
mantenere le versioni perché non è un
proprietà intrinseca del sistema che
i dati hanno il controllo delle versioni e quando sono
l’applicazione di questi dati ho per memorizzarlo
localmente in modo che io sappia che sto applicando
tutto esattamente una volta
Devo immagazzinare dove sono nei log
quindi come si manifesta questo
cosa interessante che viene fuori da questo
è perché ho questa garanzia
che applicherò tutti i dati che
viene in sul log in questo modo che
E ‘disponibile in non ho più bisogno di questo
replica processo di riconciliazione in effetti
se dovessi andare a confrontare i dati su
frammenti e provare a correggere in modo proattivo
i dati che esistono sui frammenti I
introdurrebbe maggiore coerenza
problemi di quelli che risolverei perché
del modo in cui il sistema funziona così
bello ma si scopre anche che lo siamo ancora
ho bisogno di un tipo molto simile di
sistema che attraversa e confronta
i dati tra host perché quando tu
avere un cluster con terabyte
terabyte di dati in esso si deve
controlliamo costantemente cose come
bit put per potenziali bug e
potenzialmente correggendoli così con il
risparmio di denaro enorme risparmio un altro
cosa che cambia è quando stai facendo
migrazioni dei dati così su Twitter come a
la maggior parte dei posti in cui costruiamo un nuovo sistema
generalmente vogliamo approfittare di
i vantaggi che abbiamo costruito per
migrare alcuni servizi dal vecchio
sistemi su cui si trovavano sul nuovo
sistema e per fare questo per un database e
per mantenere vivo quel servizio e non avere
qualsiasi tempo morto, ciò che generalmente si fa
inviare richieste soprattutto richieste di scrittura
che stanno arrivando a quel dato bit che
stanno entrando in servizio per entrambi
banche dati e poi sullo sfondo si
recuperare informazioni vecchie dal vecchio
sistema di database al nuovo in un
archivio di valori chiave eventualmente coerente
con la risoluzione del conflitto questo risulta
essere abbastanza banale da fare è sufficiente
inviare i diritti a entrambi questi sistemi voi
copia i dati su ciò che vuoi
copialo
la risoluzione del conflitto si prende cura di
tutto per te quando hai finito
copiando puoi semplicemente cambiare le tue letture
verso il nuovo sistema abbastanza semplice per
il modello più consistente questo
non è più il caso se voglio fare
qualcosa come spostare un’applicazione che
era sul mio sequel o nei nostri DBMS su
Manhattan potremmo avere operazioni
in esecuzione che si basano sui dati che
esiste nel sistema durante l’ aggiornamento
che dati cose come confrontare e impostare così
Devo scrivere un codice extra su un per
base applicativa per assicurarsi che il
dati viene popolata correttamente tra la
due sistemi e che manteniamo
integrità e correttezza un cambiamento
abbiamo dovuto fare nello stesso modo è
il processo di come aggiungiamo e rimuoviamo
note dal cluster che è
qualcosa che chiamiamo topologia
transizione quindi ancora una volta
sistema coerente facendo una topologia
transizione spostando un frammento da un vecchio
la serie di host per un nuovo set di host è
è piuttosto facile iniziare a dirigere i diritti
che appartengono a quel frammento al nuovo
set di repliche e quello vecchio tu
snapshot dei dati che copi su quando
è fatto per essere copiato mentre tu muovi tutto
dei diritti e legge al nuovo
set di repliche perché l’ordine non ha importanza
questo funziona da solo ma con
il modello più fortemente coerente tu
devo pensare un po ‘più difficile
perché non puoi semplicemente iniziare a inviare
scrive sul nuovo set di host che hai
per cambiare la macchina di stato della topologia
macchina a stati di transizione che gestisce
l’aggiunta di host per ospitare
questi nuovi componenti quindi la prima cosa
lo fai ora è dire invece di accettare
i diritti dicono solo che ho una nuova serie di
repliche nel cluster e mi interessa
gli aggiornamenti che stanno arrivando
questo registro per questo grafico così al molto
meno
cancellarli dal registro prima che io abbia un
possibilità di leggerli quindi è un’istantanea
i dati e copiarli come normali e
quindi aggiungi questo nuovo stato allo stato
macchina che alla fine coerente
i dati sono un no op ma per forza
dati coerenti che legge da un registro
dice dammi una possibilità di recuperare tutto
gli aggiornamenti che ho perso dal
registrati dal punto in cui ho ottenuto il
istantanea è necessario fare questo recuperare
prima di iniziare ad accettare le richieste
altrimenti non appena inizi ad accettare
richieste da questi host e dicendo
che stanno cercando di ascoltare il
risposte a cui questi host rimandano
il coordinatore che sei improvvisamente sarà
prendendo una richiesta che stava prendendo dieci
millisecondi e rendendolo multiplo
minuti o tutto il tempo necessario per
questi nodi per raggiungere la corrente
dichiari sul registro un’ultima modifica che noi
fatto era in come sarà in come noi
implementato TTL
quindi un TTL o un tempo per vivere è davvero
funzionalità utile in cui è possibile indicare
che un valore non dovrebbe più essere
leggibile dopo un certo punto nel tempo
potresti usare un TTL perché lo sei
raccogliere una sorta di dati utente e
non è più rilevante dopo alcuni
giorni in modo da non voler essere in grado di
leggerlo vuoi che venga ripulito
potresti usarlo perché lo è un utente
attivo per 30 giorni o qualcosa così tu
ci chiedono quando un utente accede
questo utente è attivo imposta il TTL per 30
giorni automaticamente dopo 30 giorni il
utente non sarà più troppo attivo
se non hanno effettuato nuovamente l’accesso, quindi
il modello alla fine coerente è suo
implementato in modo abbastanza semplice
modo se leggete un pezzo di dati da un
nodo e quel nodo pensa che quello
pezzo di dati è scaduto
semplicemente non te lo restituisce questo
sarà soggetto al normale
quantità di disallineamento dell’orologio che si verifica attraverso
nodi in un data center ma risulta
quello per il nostro modello alla fine coerente
va bene non rompere nulla
tutto funziona ancora come ci si aspetta
lavorare, ma ovviamente per forza
modello coerente non va più bene
perché l’esplorazione di questi dati è
nei dati che manipolano l’evento come qualsiasi altro
altro e sappiamo che tutti questi
gli eventi devono accadere nello stesso ordine
quindi potete immaginare affidamento sull’orologio
del nodo e questi nodi hanno l’orologio
inclinare e fare qualcosa come un check-in
impostare l’operazione e hanno trovato alcuni nodi
stai facendo un’operazione di check-in
contro il valore che esiste e via
alcuni nodi lo stai facendo contro il
valore che il nodo pensa non esiste
ora hai introdotto una divergenza in
nei tuoi dati hai un
incoerenza tra le tue repliche e
questo è esattamente il caso che eravamo
cercando di evitare
quindi per andare in giro che noi
deciso di non fidarsi più di un individuo
concetto di nodi del tempo invece di
contando sull’orologio delle note che inviamo con
ogni operazione indica un timestamp
a che ora la nota dovrebbe pensare che siamo noi
può fare questo perché il nostro registro distribuito
l’architettura consente un singolo master a
scrittore unico per ogni registro e quindi noi
può garantire che questo concetto di tempo
che questo orologio è sempre monotono
aumentando così quando inviamo ciascuno
operazione il nodo aggiorna il suo concetto
di tempo e ora solo attraverso l’operazione
i confini possono essere scaduti a causa di
TTL e in questo modo garantiamo tutto
queste cose accadono nello stesso ordine
si tratta di una soluzione piuttosto interessante è
un uso molto popolare del nostro database e
non è generalmente TTLs non è qualcosa
che hai visto più forte
sistemi coerenti
quindi un’ultima cosa che dirò è che a
l’ inizio del discorso che abbiamo discusso
cos’è che gli utenti del nostro
database desiderato e per supportare
quello che volevano abbiamo fatto tutti questi
modifiche al back-end del database
abbiamo introdotto piuttosto diverse
modelli di coerenza che vivono fianco a fianco
e la questione viene Siamo riusciti a
aggiungere funzionalità senza interrompere
l’ esperienza degli utenti è tale da poter essere utilizzata
questa nuova modalità del database tutti i
l’utente deve fare è quando il provisioning del
set di dati nell’interfaccia utente Web che scelgono a
tipo di consistenza più forte e quando
facendo una richiesta tramite il nostro cliente
impostare una garanzia di coerenza più forte o
se stanno facendo un’operazione che
non esisteva prima come un confronto e
impostare che possono utilizzare una semplice API per questo
e non solo questo se provano a farlo
qualcosa che non pensiamo sia sicuro
fare contro questi dati per esempio se
inviano una richiesta che sta tentando di
aggiornare in un fan alla fine
modo coerente un set di dati che è
fortemente coerente è sto cercando di
invia una scrittura non attraverso il replicato
log ispezioniamo quella richiesta che decidiamo
che non è sicuro e poi lo rimandiamo indietro
un messaggio di errore molto lungo ma chiaro
dicendo che cosa è che stanno cercando di
fai perché non va bene e cosa potrebbero
fare invece e in questo modo manteniamo
una delle cose più importanti su
questo database che stavamo cercando di
raggiungere quando lo abbiamo costruito che è quello
è molto usabile e facile per le persone così
che possono adottare rapidamente senza
portare la nostra squadra in loop per la maggior parte
problemi
grazie mille
contesto e alcune specifiche pratiche
su come costruiamo una consistenza più forte
garanzie nel nostro valore chiave esistente
negozio su Twitter
il mio nome è Baz I am on the core storage
squadra su Twitter siamo una delle squadre
che fornisce come servizio gestito
deposito per gli ingegneri dell’azienda
chi costruirà le loro applicazioni lo farò
darti un secondo per seguirmi
Twitter uno dei modi in cui lo facciamo
e lo stanno facendo da un po ‘ora
è con un database che chiamiamo
Manhattan è la nostra distribuzione
archivio di valori-chiave è la chiave primaria
valore negozio Twitter che abbiamo costruito da
il ground up circa quattro anni fa
Manhattan non esisteva e oggi è così
il negozio canonico per un sacco di molto
dati importanti alle cose dell’azienda
come tweets Dati dell’inserzionista DMS e a
intera lunga coda di altre applicazioni
Ti darò un po ‘di contesto per la
database tra le altre ragioni uno dei
le cose per cui abbiamo costruito Manhattan erano
essere molto facile da adottare per gli sviluppatori
stoccaggio e entrare rapidamente in produzione
con i loro servizi al fine di farlo
abbiamo sottolineato alcune cose che forniamo
accesso self-service al database
attraverso un’interfaccia web cerchiamo di nasconderci
come molte complessità di infrastruttura come
possiamo dai nostri clienti l’altro
ingegneri su Twitter cose come fare
replica globale trasparente attraverso
tutte le regioni dei nostri data center
permettiamo ai clienti di condividere lo spazio
grandi cluster questo riduce il
tempo di provisioning quando chiedi ascia
stoccaggio e riduce il carico sul
sviluppatori da dover impostare e
gestire nuovi cluster ogni volta che qualcuno ha
un nuovo caso d’uso e ne forniamo anche alcuni
nifty visibilità automatica e
osservabilità e allerta in modo che
le persone hanno visibilità su come loro
tu
utilizzando il database ora come con qualsiasi
servizio di successo in quanto ottiene di più
popolare e ottiene più persone che adottano
abituarsi a usarlo e loro vogliono
iniziare a usarlo per casi d’ uso per i quali
non era esattamente progettato nel nostro caso
ciò potrebbe significare che qualcuno che era
usando questa chiave alla fine coerente
value store vuole iniziare a usarlo per
parti dei loro dati che necessitano di maggiore
garanzie di consistenza quando provano a
fai questo e loro non possono con il nostro sistema
causa molto dolore significa questo
devono fare dei compromessi che loro
non vogliono fare o che non sono
felice con e entrambi fanno quelli
compromessi attraverso l’utilizzo del nostro sistema o
attraverso l’ utilizzo di un sistema diverso come in
il nostro DBMS che non fornisce alcuni di
le garanzie che ti forniamo così
un ingegnere il cui compito è risolvere
questi problemi per i tuoi clienti sono
presentato con una scelta una scelta che noi
vedi un sacco di cose che fai costruisci una nuova
servizio o utilizzare un nuovo servizio esistente
accanto in parallelo al al
servizio che devi già risolvere
questi problemi o ne crei di nuovi
funzionalità nel servizio esistente oggi
Ora questa è una scala e non ho bisogno di
ti dico che non vuoi essere presente
il lato più lontano della scala in cui tu
costruire un software gonfiato che non è molto
bravo in qualsiasi cosa ma anche quando lo sei
costruire infrastrutture non sempre
voglio creare servizi che sono anche troppo
specifico e ci sono alcuni motivi per
quello sta facendo funzionare più sistemi dentro
la produzione può essere davvero dolorosa ogni
il sistema avrà un altro
profilo operativo ogni sistema è
andando ad avere i suoi piccoli capricci e
sarà doloroso per il tuo
ingegneri di guardia per conoscere ogni sistema
in profondità un altro è quello per
infrastrutture complesse un sacco di cose
stanno per essere comune tra questi
servizi per un database per esempio
hai sempre bisogno di gestire
i tuoi nodi di cui avrai sempre bisogno
per spostare i dati in giro e si sta andando a
devi ricostruire questi componenti
per il
sistemi o cercare di astrarre continuamente
componenti fuori dai vostri sistemi che possono
hanno rendimenti decrescenti e probabilmente
la più grande ragione che non vuoi
molti sistemi separati sono io
ti garantisco che i tuoi clienti no
voglio parlare con cinque diversi database
con cinque diverse API ciascuna
fornisce una garanzia leggermente diversa
o funzione così in realtà vuoi essere
da qualche parte qui sulla scala in cui sei
costruire sistemi specializzati che sono
bravi in quello che fanno ma possono evolversi
in modo logico e riflessivo per
fornire più funzionalità al tuo
i clienti quindi è quello che volevamo fare
per risolvere questo problema per i nostri clienti
e gli ingegneri su Twitter e in
per parlare di come l’abbiamo fatto lo farò
diamo a voi ragazzi una panoramica del
architettura architettonica del nostro
alla fine database coerente sarò
andare piuttosto rapidamente per un sacco di generale
concetti se si ha familiarità con
sistemi distribuiti o distribuiti
database molto di questo andrà a cercare
molto familiare ma se non si sente libero di farlo
fare domande dopo il discorso o trovarmi
alla conferenza come un buon posto per
iniziare come qualsiasi con il database è con
il modello di dati Manhattan, come ho detto, è a
negozio di valore chiave e abbiamo diviso le nostre chiavi
in due componenti una chiave di partizione o P
chiave e una chiave locale o L chiave locale
sono memorizzati insieme sulla stessa macchina
sotto la chiave di partizione che hanno
località che è il motivo per cui noi li chiamiamo
e questo significa che puoi farlo
Interrogazione a lato dell’intervallo interessante per
istanza in questo set di dati se il tasto p
è un ID utente puoi dire qualcosa di simile
prendi tutte le chiavi che iniziano con
il profilo di parole per questo particolare
utente e otterresti l’utente
Profilo Questo dovrebbe essere familiare a voi
se hai usato Cassandra o BigTable come
uno schema a righe e colonne o se lo hai
dynamodb utilizzato come chiave hash e intervallo
chiave così prendiamo queste chiavi e noi
distribuirli attorno al cluster
il modo in cui lo facciamo è l’hashing
partizione e chiave
in modo casuale in un frammento e poi
replicando quei frammenti e
distribuendoli ai nodi nel
cluster quando vuoi fare una richiesta
si invia un client invia la loro richiesta a
uno dei tanti apolidi simmetrici
i nodi coordinatori prendono i nodi
richiesta prendere la chiave da esso trovare il
shard che quella chiave appartiene a trovare il
nodi di archiviazione su cui vive la shard
e quindi inoltra tali richieste in
parallelo a tutti quei nodi di archiviazione
in attesa di una risposta tale risposta
potrebbe essere un successo se è giusto
potrebbe essere l’ ultimo valore se si tratta di una lettura
ora quando dico che il coordinatore
i nodi inoltrano questi dati in parallelo a
tutti questi nodi di archiviazione che dovrebbero
essere un regalo immediatamente che sono
parlando di un quorum basato alla fine
sistema coerente specificamente in questo
caso usiamo stile Dinamo eventuale
coerenza come nella Dinamo amazzonica
carta e abbiamo l’ultima destra vince
risoluzione dei conflitti facendo ciò che possiamo
inoltrare le richieste in parallelo a tutti
degli ospiti e quelle richieste possono
riuscire e fallire indipendentemente da ciascuno
altro senza necessariamente influenzare il
successo complessivo dell’intera richiesta
e finché si fanno richieste
a un quorum di host se questo è importante
a te in questo caso che sarebbero due
su tre e quelle richieste hanno successo
sei sicuro di essere sicuro
livelli di coerenza come leggi il tuo
diritti in questo caso quindi se questi sono
diritti sul database e uno di essi
fallisce a causa di una partizione di rete o
a causa di un riavvio a rotazione e
successivamente fai una lettura da a
database e in tutta la lettura anche
ha successo anche contro un quorum di host
se uno di questi host ha fallito in precedenza
sei sicuro di vederne almeno uno
versione dei dati che è l’ultima
versione che hai scritto e di
Certo che non possiamo chiamarlo in modo definitivo
coerenza se non lo facciamo alla fine
i dati coerenti tra gli host così noi
avere un processo anti entropia che funziona
sullo sfondo chiamato replica
riconciliazione
questo va e confronta i frammenti attraverso
ogni replica assicurandosi che abbiano
gli stessi dati e se non lo fanno
copia quei dati, quindi questi sono tutti
alcuni semplici standard
concetti perché dovremmo scegliere di costruire un
sistema in questo modo
Il vantaggio principale che si ottiene da
costruire un sistema come questo è super
alta disponibilità perché tutto il
nodi di archiviazione sono uguali tra loro che
non abbiamo una relazione di padronanza noi
non hanno latenza e disponibilità
singhiozzo da cose come il failover e
master rielezione e perché abbiamo scelto
per inviare la richiesta in parallelo a tutti
di questi host questa è una latenza
trade-off del throughput sei essenzialmente
in attesa di una migliore risposta di n da
queste repliche e stai ottenendo il
migliore latenza possibile del sistema
può fornire in qualsiasi momento e si ottiene anche
semplicità e semplicità è dentro
scambio per forse un po ‘meno di
modello di coerenza intuitivo che ottieni per ultimo
vince il diritto o davvero con qualsiasi tipo di
risoluzione del conflitto hands-off un modo per
spostare in modo trasparente i dati in modo asincrono
replicare i dati da un set di host a
un altro e avere questi dati senza soluzione di continuità
integrato nei dati esistenti nel
sistema quindi se copio i dati tramite
riconciliazione delle repliche o se io
replicare i dati da un altro
regione che combina solo con i dati
che è già sul sistema in modo
ciò rende la nostra replica incrociata
storia molto bella molto facile per le persone
usa e non devi pensarci
come funzionano i miei dati cross-region
il database ma come ho detto per alcuni
la gente non è abbastanza quando è
non abbastanza un caso d’uso è molto simile a
qualsiasi altro tipo di programmazione concorrente
quando hai bisogno di unicità o controllo e
imposta il vincolo di fronte a concorrenti
aggiornamenti al database quindi un esempio di
che potrebbe essere se due utenti stanno provando a
entrambi riservano un nome utente
non solo ho bisogno solo di uno di questi
gli utenti alla fine riescono a prenotare
questo nome utente non posso avere gare che
risultato in entrambi pensando questo
sono riusciti a riservare il nome utente
perché questo può rompere il business
logica della tua domanda quindi per
istanza se entrambi questi utenti ci hanno provato
Riserva
entrambi hanno visto che il nome utente era gratuito
entrambi hanno detto di assegnarmelo, se solo lo fosse
se entrambi hanno avuto successo su questo
incarico ma solo la seconda persona
chi è successo a fare quella richiesta
è riuscito questo è un comportamento molto imbarazzante
per la tua applicazione da superare
e si applica anche attraverso le regioni
a livello globale così due persone potrebbero provare
per prenotare un nome utente di cui uno è in
Uno di loro a Chicago è addirittura a Nairobi
se stanno parlando con dati diversi
centri dovrebbero ancora ottenere questi stessi
garanzie e nello stesso esempio tu
voglio un’altra cosa che è un de Missa
T dei tuoi aggiornamenti se invio un aggiornamento a
il database per prenotare questo nome utente in
In caso di fallimento, voglio che fallisca
ovunque nel caso del successo che voglio
per riuscire ovunque non riesco a ottenere
in uno stato in un fallimento Canario dove
una minoranza di ospiti pensa che a
il nome utente è riservato e non posso
garantire una lettura prevedibile quando vado
torna indietro e prova a vedere chi ha questo
nome utente questo è uno stato che puoi
entrare con la coerenza finale e
questo stato sarà risolto sia in
una direzione o l’altra a seconda di
se questo host esistente muore o meno
quindi è inaccettabile per alcuni casi d’uso
quindi ora sappiamo che abbiamo questo tipo di
genuino bisogno di una maggiore coerenza
modella come adattiamo la nostra corrente
architettura per supportare questo
possiamo aggiungere un nuovo componente al nostro
percorso di richiesta che è log in particolare
log distribuiti sequenziali replicati
nella forma per noi di Twitter
registro distribuito che è di recente aperto
libreria di log di origine creata in cima a a
contabile irregolare lo scopo di a
log sequenziale è quello di tutti
aggiornamenti che entrano in questo sistema in
questo registro può essere letto nello stesso modo
ordine da tutti i consumatori in uscita
diventa complicato quando si replica
questo registro per la durata e voi
distribuire questo registro per resilienza e
scalabilità e il registro deve fare i conti
concetti come consenso o padronanza
con failover e scherma e deve
ottenere tutti questi concetti complicati giusti
ora questo tipo di componente sta diventando
sempre più popolare in molti
diversi tipi di infrastrutture se tu
erano all’ultimo discorso qui poi hai visto
Kafka che è un tipo di distribuito
registro e quindi non parlerò di come questi
i log sono implementati ma parlerò
su come usiamo questo registro quali sono alcuni
delle complessità dell’interazione quando
introduciamo questo nuovo tipo di componente
nel nostro percorso di richiesta e avere questo nuovo
tipo di modello di coerenza, così ho detto
prima che tutte le chiavi siano
partizionato in frammenti questo frammento è
questa unità granulare finale di
partizionamento e distribuzione nel
sistema in modo da poter spostare i frammenti in
tra gli host quello che posso scegliere di fare è
Dì che tutte le operazioni che stanno andando
per aggiornare o agire su un frammento devono andare
attraverso un registro e posso fare questo registro
per infrastruttura di shard e quindi posso
avere tutti i nodi di archiviazione che possedevano
questo frammento consuma tutti i loro aggiornamenti
per quella scheggia dal registro e
avere questa garanzia che tutti quelli
gli aggiornamenti saranno garantiti
consegnato e consegnato in ordine da
il log e ora una volta che ho questo posso
fare queste operazioni praticamente ogni
tutto ciò che voglio che siano lì
può essere letto o scritto così com’erano
prima o posso iniziare a inviare il confronto
e impostare le operazioni che posso iniziare a inviare
operazioni di incremento posso inviare qualsiasi tipo
di funzionamento che è basato deterministico
sui dati che arrivano nel
operazione stessa e il dato che
esiste già nel database che è
garantito per essere lo stesso su ogni
nodo di archiviazione nel momento in cui quello
operazione viene elaborata in modo che possiamo già
vediamo che introducendo questo possiamo
risolvere alcuni dei problemi che eravamo
preoccupato prima di prendere il
esempio di prenotazione Posso modellare a
prenotazione di un nome utente come check-in
imposta operazione in cui dico se un nome utente
è gratuito assegnare il mio ID utente a quello
nome utente e due utenti che lo sono
fare contemporaneamente questa richiesta
appare in questo registro in un ordine che
l’ordine non ha importanza perché
lo stanno facendo contemporaneamente e sia
l’ordine è valido ma ciò che è importante è
che tutti i nodi di archiviazione di tutto il
le repliche che elaborano questa richiesta vedono
lo stesso ordine, quindi cosa finirà
accadendo è quello il primo che
entra nel registro sarà in grado di prenotare
quel nome utente e il secondo lo farà
fallire la sua condizione di controllo e non prenotare
il nome utente e vedere una felice applicazione
livello di errore questo tipo di semplice cambiamento
al modello di messaggistica consente il nostro
garanzie da rafforzare abbastanza a
un po ‘, quindi rimpiccioliamo un po ‘ e
vedere come questo si inserisce nel più grande
architettura ora quando un cliente invia un
richiesta a un coordinatore invece di
inoltrare tale richiesta direttamente al
nodi di archiviazione in avanti del coordinatore
per il log che possiede il frammento per
su quale chiave vive e poi su
nodi di archiviazione
consumare da quel registro riprodurre
operazione e rispondere con ancora il
successo se è giusto il valore se
è una lettura o qualunque sia il risultato
è del tuo complesso più complesso
operazione di nuovo al coordinatore
ora se noti che ho una nuova garanzia
qui che non avevo prima che sia
che se il diritto entra nel registro lo so
quello che vedranno i nodi di archiviazione
e se un nodo di archiviazione elabora un
operazione so che tutti gli altri
nodi di archiviazione che lo elaborano
l’operazione restituirà la stessa risposta
perché hanno gli stessi dati quindi ora io
può iniziare a fare cose più interessanti
con il mio modello di richiesta in modo da poter mantenere
le stesse garanzie che voglio avere
riducendo la latenza sul client
lato per ogni richiesta data così per
esempio diciamo che lo so per certo
tutti i miei diritti e tutte le mie letture
un mio set di dati andrà
attraverso questo log sequenziale bene ora
posso dire se sto inviando una scrittura al più presto
come quella scrittura entra nel registro ho finito io
sappi che quella scrittura sarà alla fine
essere applicato ai nodi di archiviazione così io
solo bisogno di aspettare che il registro agisca
che ha questo diritto duraturo prima di me
può restituire un successo al cliente
e so che ogni successiva lettura lo farà
essere citato dietro quella scrittura nel registro
quindi vedrà la scrittura come io
aspettati e quando invio quella lettura
o se invio un messaggio più complesso
operazione che ha bisogno di un risultato solo io
è necessario attendere per uno degli archivi
nodi per rispondere perché so tutto
gli altri nodi di archiviazione risponderanno
con gli stessi dati quindi questo lo rende sicuro
tipi di operazioni forti accadono a
un po ‘più veloce possiamo aspettare
per la risposta del registro o il più veloce
risposta da un host ma posso ancora fare
qualcosa di interessante posso dire di esserlo
in attesa di un quorum di risposte prima
non sarebbe il mio modello alla fine coerente
Come
ma aspetto un quorum di risposte ora
quindi se invio un diritto o se invio un cast
o un incremento o qualcosa che aspetterò
per un quorum di risposte a tornare
e se lo faccio lo so
richiesta è durevole e coerente sul
note di archiviazione stesse e quando invio
una lettura successiva perché non l’ho fatto
cambia il mio percorso di richiesta Ho solo aggiunto un
nuova opzione per la richiesta può contenere
questo database posso inviare una lettura
il normale fan-out alla fine coerente
percorso e quando lo faccio ottengo tutto il
benefici che stavo ricevendo prima
una richiesta alla fine coerente alta
disponibilità bassa latenza senza mangiare
qualsiasi costo di passare attraverso il registro
ma continuo a fare aggiornamenti in questo
moda più fortemente coerente così questo
è un modello interessante e in a
poche parole questo è il modo possiamo aggiungere questo registro
componente nel database da aggiungere
consistenza più forte quindi vediamo cosa
sono i risultati che ne derivano
bene prima abbiamo guadagnato quello che è
stavamo cercando di guadagnare perché gli aggiornamenti
sono ordinati per frammento e le chiavi sono
hash a caso in frammenti ma
coerentemente in frammenti noi efficacemente
acquisito in ordine di aggiornamenti su una chiave
base linearizza l’abilità per le nostre chiavi
tecnicamente abbiamo per gli aggiornamenti per
tutto nel frammento ma perché tu
come utente non so per certo se due
le chiavi finiranno nello stesso shard tu
non fare affidamento su ciò è importante
per notare che non abbiamo pieno
transazioni distribuite tra i frammenti
questo è un problema più complesso ed è
qualcosa su cui dovrebbe essere costruito
cima a questo sistema più di base anche noi
abbiamo o possiamo dire che abbiamo mantenuto il fallimento
isolamento a livello di shard perché tutto
dei nostri diritti passano attraverso i log che sono
posseduto da frammenti se abbiamo un singhiozzo o
un problema o un problema con un individuo
ceppo
quel problema è limitato a molto
piccolo frammento dello spazio chiave che
appartiene a quel frammento e anche perché
abbiamo solo aggiunto questo nuovo percorso nel nostro
architettura invece di sostituirla
completamente abbiamo questa capacità di fare a
coppia cose non solo possiamo mescolare forte
e infine set di dati coerenti
all’interno dello stesso cluster possiamo effettivamente
in una certa misura mescolare forte ed eventualmente
richieste coerenti all’interno degli stessi dati
set e questo è ciò che intendo quando dico
che stiamo fornendo flessibile
livelli di consistenza che un utente può tornare indietro
e avanti attraverso questo continuum in mezzo
super alta disponibilità e carina
forte per oggetto linearizza l’abilità di
basta modificare il tipo di richiesta
fare su una base per richiesta al
database e questo è davvero potente per
i nostri clienti e ti permette di ottenere
esattamente quello che volevi nel sistema
esattamente il tempo che vuoi
Certo, abbiamo prima fatto dei compromessi
il trade-off è ovvio che abbiamo aggiunto
un nuovo componente non è il nostro
componente particolarmente semplice in
percorso di richiesta e così in media siamo
aggiungerò un po ‘ di latenza nel
centro dati locale che potrebbe essere pochi
millisecondi di latenza, se lo sei
parlando di fare coordinamento attraverso
regioni che sono vincolate dal
Deludentemente bassa velocità della luce e
quindi avrai un ordine
magnitudine più latenza aggiunta al tuo
richieste che devono coordinarsi lontano
in tutto il mondo abbiamo anche tutto il resto
abbiamo provato a isolare i guasti esposti
noi stessi a questa cosa che eravamo
cercando di evitare quale è il singhiozzo di latenza
quindi quando ci sono alcuni tipi di problemi
o rielezioni su un singolo registro
che rallentano gli aggiornamenti per un
il frammento individuale in cui un cliente vedrà
le loro alte agenzie percentuali
aumentare e va bene per te
questo ha un compromesso che devi essere
va bene come sviluppatore di applicazioni
e infine uno interessante
perché abbiamo detto che tutti questi
gli aggiornamenti devono avvenire in ordine e loro
devono essere applicati per mantenere
l’integrità del database e il
dati sul database allora abbiamo il
situazione in cui, se per qualche motivo
le repliche non possono applicare un’operazione che
legge da un flusso da un registro il
l’unica opzione che abbiamo è
interrompere completamente le operazioni per quel registro
quindi perché, perché non potremmo essere in grado di applicare
un’operazione normalmente dovrebbe essere tutto
applicare ma operando a noi scala
prendere in considerazione che lì
potrebbero essere bug che dobbiamo prendere in
conto che potrebbe esserci qualche tipo di
problema di corruzione eccezionale e quello
le singole repliche ora non possono continuare
per elaborare le operazioni da quel registro e
abbiamo una indisponibilità formale questo può
essere spaventoso certamente suona spaventoso ed è
dove cose come eccellente
osservabilità allerta eccellente
entrano in gioco strumenti eccellenti da realizzare
sicuro che se questo accade perché tu
dobbiamo rendere conto di tutte le possibilità che noi
conoscilo subito e risolviamo
il più rapidamente possibile, ecco cosa
sembra quando aggiungiamo questo nuovo percorso
ed è importante ora che lo hai
pensa a come è questo nuovo modello
che abbiamo aggiunto diverso dal
modello esistente e come lo usiamo
nuovo modello e gestire i nostri cluster con
questo nuovo modello in un modo che non lo è
speciale o unico che funziona solo con
il sistema che avevamo già così
per noi e per i nostri clienti stiamo aggiungendo
qualcosa senza perdere troppo
quando penso a come questo evento questo
è alla fine coerente e questo
modello fortemente coerente sono diversi
la prima cosa che mi viene in mente
è dove l’autorità dei tuoi dati
viene dallo stile della dinamo
modello alla fine coerente
l’autorità dei tuoi dati è consegnata
insieme ai tuoi valori nella forma di a
versione o timestamp questa versione
l’informazione è ciò che viene applicato al
back – end e decide se i nuovi dati possono
sovrascrivi i vecchi dati quindi in questo esempio
abbiamo valori abbiamo una chiave con valore
X alla versione 1 già su queste note
e una nuova chiave è l’aggiornamento di quella chiave
sta arrivando con il valore Y alla versione 2
e l’ unica ragione per la ragione
l’aggiornamento è accettato è perché il
la versione è più recente è interessante
perché disaccoppia efficacemente il
autorità dei dati dall’ordine in
che i dati arrivano è ciò che dà
noi che la risoluzione del conflitto è perché
della risoluzione del conflitto è cosa
ci dà le belle proprietà che noi
ottenuto prima è quello che ci dà il
idempotenza degli aggiornamenti che entrano in
il database ma è interessante
motivo anche per i benefici che
fornisce il nuovo modello è completamente
è diverso l’ordine degli aggiornamenti
tutto ciò che conta per i dati nel
back end e se voglio mantenere
attorno ad alcune informazioni sulla versione di me
devono mantenere che indipendentemente
ogni singolo host e se lo voglio
le informazioni sulla versione sono le stesse su a
attraverso gli host che è qualcosa che
Voglio se voglio ancora poterlo fare
rendere quelli stile alla fine coerente
richieste di quorum, quindi devo farlo
come un dettaglio di implementazione di come io
mantenere le versioni perché non è un
proprietà intrinseca del sistema che
i dati hanno il controllo delle versioni e quando sono
l’applicazione di questi dati ho per memorizzarlo
localmente in modo che io sappia che sto applicando
tutto esattamente una volta
Devo immagazzinare dove sono nei log
quindi come si manifesta questo
cosa interessante che viene fuori da questo
è perché ho questa garanzia
che applicherò tutti i dati che
viene in sul log in questo modo che
E ‘disponibile in non ho più bisogno di questo
replica processo di riconciliazione in effetti
se dovessi andare a confrontare i dati su
frammenti e provare a correggere in modo proattivo
i dati che esistono sui frammenti I
introdurrebbe maggiore coerenza
problemi di quelli che risolverei perché
del modo in cui il sistema funziona così
bello ma si scopre anche che lo siamo ancora
ho bisogno di un tipo molto simile di
sistema che attraversa e confronta
i dati tra host perché quando tu
avere un cluster con terabyte
terabyte di dati in esso si deve
controlliamo costantemente cose come
bit put per potenziali bug e
potenzialmente correggendoli così con il
risparmio di denaro enorme risparmio un altro
cosa che cambia è quando stai facendo
migrazioni dei dati così su Twitter come a
la maggior parte dei posti in cui costruiamo un nuovo sistema
generalmente vogliamo approfittare di
i vantaggi che abbiamo costruito per
migrare alcuni servizi dal vecchio
sistemi su cui si trovavano sul nuovo
sistema e per fare questo per un database e
per mantenere vivo quel servizio e non avere
qualsiasi tempo morto, ciò che generalmente si fa
inviare richieste soprattutto richieste di scrittura
che stanno arrivando a quel dato bit che
stanno entrando in servizio per entrambi
banche dati e poi sullo sfondo si
recuperare informazioni vecchie dal vecchio
sistema di database al nuovo in un
archivio di valori chiave eventualmente coerente
con la risoluzione del conflitto questo risulta
essere abbastanza banale da fare è sufficiente
inviare i diritti a entrambi questi sistemi voi
copia i dati su ciò che vuoi
copialo
la risoluzione del conflitto si prende cura di
tutto per te quando hai finito
copiando puoi semplicemente cambiare le tue letture
verso il nuovo sistema abbastanza semplice per
il modello più consistente questo
non è più il caso se voglio fare
qualcosa come spostare un’applicazione che
era sul mio sequel o nei nostri DBMS su
Manhattan potremmo avere operazioni
in esecuzione che si basano sui dati che
esiste nel sistema durante l’ aggiornamento
che dati cose come confrontare e impostare così
Devo scrivere un codice extra su un per
base applicativa per assicurarsi che il
dati viene popolata correttamente tra la
due sistemi e che manteniamo
integrità e correttezza un cambiamento
abbiamo dovuto fare nello stesso modo è
il processo di come aggiungiamo e rimuoviamo
note dal cluster che è
qualcosa che chiamiamo topologia
transizione quindi ancora una volta
sistema coerente facendo una topologia
transizione spostando un frammento da un vecchio
la serie di host per un nuovo set di host è
è piuttosto facile iniziare a dirigere i diritti
che appartengono a quel frammento al nuovo
set di repliche e quello vecchio tu
snapshot dei dati che copi su quando
è fatto per essere copiato mentre tu muovi tutto
dei diritti e legge al nuovo
set di repliche perché l’ordine non ha importanza
questo funziona da solo ma con
il modello più fortemente coerente tu
devo pensare un po ‘più difficile
perché non puoi semplicemente iniziare a inviare
scrive sul nuovo set di host che hai
per cambiare la macchina di stato della topologia
macchina a stati di transizione che gestisce
l’aggiunta di host per ospitare
questi nuovi componenti quindi la prima cosa
lo fai ora è dire invece di accettare
i diritti dicono solo che ho una nuova serie di
repliche nel cluster e mi interessa
gli aggiornamenti che stanno arrivando
questo registro per questo grafico così al molto
meno
cancellarli dal registro prima che io abbia un
possibilità di leggerli quindi è un’istantanea
i dati e copiarli come normali e
quindi aggiungi questo nuovo stato allo stato
macchina che alla fine coerente
i dati sono un no op ma per forza
dati coerenti che legge da un registro
dice dammi una possibilità di recuperare tutto
gli aggiornamenti che ho perso dal
registrati dal punto in cui ho ottenuto il
istantanea è necessario fare questo recuperare
prima di iniziare ad accettare le richieste
altrimenti non appena inizi ad accettare
richieste da questi host e dicendo
che stanno cercando di ascoltare il
risposte a cui questi host rimandano
il coordinatore che sei improvvisamente sarà
prendendo una richiesta che stava prendendo dieci
millisecondi e rendendolo multiplo
minuti o tutto il tempo necessario per
questi nodi per raggiungere la corrente
dichiari sul registro un’ultima modifica che noi
fatto era in come sarà in come noi
implementato TTL
quindi un TTL o un tempo per vivere è davvero
funzionalità utile in cui è possibile indicare
che un valore non dovrebbe più essere
leggibile dopo un certo punto nel tempo
potresti usare un TTL perché lo sei
raccogliere una sorta di dati utente e
non è più rilevante dopo alcuni
giorni in modo da non voler essere in grado di
leggerlo vuoi che venga ripulito
potresti usarlo perché lo è un utente
attivo per 30 giorni o qualcosa così tu
ci chiedono quando un utente accede
questo utente è attivo imposta il TTL per 30
giorni automaticamente dopo 30 giorni il
utente non sarà più troppo attivo
se non hanno effettuato nuovamente l’accesso, quindi
il modello alla fine coerente è suo
implementato in modo abbastanza semplice
modo se leggete un pezzo di dati da un
nodo e quel nodo pensa che quello
pezzo di dati è scaduto
semplicemente non te lo restituisce questo
sarà soggetto al normale
quantità di disallineamento dell’orologio che si verifica attraverso
nodi in un data center ma risulta
quello per il nostro modello alla fine coerente
va bene non rompere nulla
tutto funziona ancora come ci si aspetta
lavorare, ma ovviamente per forza
modello coerente non va più bene
perché l’esplorazione di questi dati è
nei dati che manipolano l’evento come qualsiasi altro
altro e sappiamo che tutti questi
gli eventi devono accadere nello stesso ordine
quindi potete immaginare affidamento sull’orologio
del nodo e questi nodi hanno l’orologio
inclinare e fare qualcosa come un check-in
impostare l’operazione e hanno trovato alcuni nodi
stai facendo un’operazione di check-in
contro il valore che esiste e via
alcuni nodi lo stai facendo contro il
valore che il nodo pensa non esiste
ora hai introdotto una divergenza in
nei tuoi dati hai un
incoerenza tra le tue repliche e
questo è esattamente il caso che eravamo
cercando di evitare
quindi per andare in giro che noi
deciso di non fidarsi più di un individuo
concetto di nodi del tempo invece di
contando sull’orologio delle note che inviamo con
ogni operazione indica un timestamp
a che ora la nota dovrebbe pensare che siamo noi
può fare questo perché il nostro registro distribuito
l’architettura consente un singolo master a
scrittore unico per ogni registro e quindi noi
può garantire che questo concetto di tempo
che questo orologio è sempre monotono
aumentando così quando inviamo ciascuno
operazione il nodo aggiorna il suo concetto
di tempo e ora solo attraverso l’operazione
i confini possono essere scaduti a causa di
TTL e in questo modo garantiamo tutto
queste cose accadono nello stesso ordine
si tratta di una soluzione piuttosto interessante è
un uso molto popolare del nostro database e
non è generalmente TTLs non è qualcosa
che hai visto più forte
sistemi coerenti
quindi un’ultima cosa che dirò è che a
l’ inizio del discorso che abbiamo discusso
cos’è che gli utenti del nostro
database desiderato e per supportare
quello che volevano abbiamo fatto tutti questi
modifiche al back-end del database
abbiamo introdotto piuttosto diverse
modelli di coerenza che vivono fianco a fianco
e la questione viene Siamo riusciti a
aggiungere funzionalità senza interrompere
l’ esperienza degli utenti è tale da poter essere utilizzata
questa nuova modalità del database tutti i
l’utente deve fare è quando il provisioning del
set di dati nell’interfaccia utente Web che scelgono a
tipo di consistenza più forte e quando
facendo una richiesta tramite il nostro cliente
impostare una garanzia di coerenza più forte o
se stanno facendo un’operazione che
non esisteva prima come un confronto e
impostare che possono utilizzare una semplice API per questo
e non solo questo se provano a farlo
qualcosa che non pensiamo sia sicuro
fare contro questi dati per esempio se
inviano una richiesta che sta tentando di
aggiornare in un fan alla fine
modo coerente un set di dati che è
fortemente coerente è sto cercando di
invia una scrittura non attraverso il replicato
log ispezioniamo quella richiesta che decidiamo
che non è sicuro e poi lo rimandiamo indietro
un messaggio di errore molto lungo ma chiaro
dicendo che cosa è che stanno cercando di
fai perché non va bene e cosa potrebbero
fare invece e in questo modo manteniamo
una delle cose più importanti su
questo database che stavamo cercando di
raggiungere quando lo abbiamo costruito che è quello
è molto usabile e facile per le persone così
che possono adottare rapidamente senza
portare la nostra squadra in loop per la maggior parte
problemi
grazie mille
Please follow and like us: