In che modo un'azienda come Amazon evita i colli di bottiglia accedendo al livello del database?


29

Se immagini un'azienda come Amazon (o qualsiasi altra grande applicazione web di e-commerce), che gestisce un negozio online su vasta scala e ha solo una quantità limitata di articoli fisici nei suoi magazzini, come possono ottimizzarla in modo tale che non ci sia collo di bottiglia singolo? Naturalmente, devono disporre di un numero di database con replica e di molti server che gestiscono il carico in modo indipendente. Tuttavia, se più utenti vengono serviti da server separati ed entrambi tentano di aggiungere lo stesso articolo al carrello, per il quale ne rimane solo uno, deve esserci una "fonte di verità" per la quantità lasciata per quell'articolo. Ciò non significherebbe che almeno tutti gli utenti che accedono alle informazioni sul prodotto per un singolo articolo devono eseguire una query sullo stesso database in serie?

Vorrei capire come è possibile gestire un negozio così grande utilizzando il calcolo distribuito e non creare un enorme collo di bottiglia su un singolo DB contenente informazioni di inventario.


Architettura di Amazon a metà degli anni 2000 (ancora rilevante per la tua domanda): highscalability.com/amazon-architecture
Joeri Sebrechts,

Questo succede anche con i posti sugli aerei (o per le vacanze al sacco in cui un articolo nel carrello rappresenta un volo lì, un'auto a noleggio, un soggiorno in hotel e un volo di ritorno), con molte agenzie diverse che vendono gli stessi posti sui rispettivi siti . Le soluzioni sono una miriade, ma tutte si riducono ad avere un database di verità finale con lo stato effettivo per ogni parte da qualche parte.
Remco Gerlich,

1
@RemcoGerlich: il modo in cui dici "un database di verità finale" mi fa pensare a una singola macchina con il grande database sacro su di esso. In realtà, ciò che accade per i dati critici è piuttosto che tutte le transazioni raggiungono più server contemporaneamente, assicurando che tutti quei database siano sempre sincronizzati.
Arseni Mourzenko,

Risposte:


27

Tuttavia, se più utenti vengono serviti da server separati ed entrambi tentano di aggiungere lo stesso articolo al carrello, per il quale ne rimane solo uno, deve esserci una "fonte di verità" per la quantità lasciata per quell'articolo.

Non proprio. Questo non è un problema che richiede una soluzione tecnica perfetta al 100%, poiché entrambi i casi di errore hanno una soluzione aziendale che non è molto costosa:

  • Se si comunica erroneamente a un utente che un articolo è esaurito, si perde una vendita. Se vendi milioni di articoli ogni giorno e questo accade forse una o due volte al giorno, si perde nel rumore.
  • Se accetti un ordine e, durante l'elaborazione, scopri che hai esaurito l'articolo, lo informi solo al cliente e dai loro la possibilità di attendere fino a quando non puoi rifornire o annullare l'ordine. Hai un cliente leggermente seccato. Ancora una volta non è un grosso problema quando il 99,99% degli ordini funziona bene.

In effetti, di recente ho sperimentato da solo il secondo caso, quindi non è ipotetico: questo è ciò che accade e come Amazon lo gestisce.

È un concetto che si applica spesso quando si ha un problema che in teoria è molto difficile da risolvere (sia in termini di prestazioni, ottimizzazione o altro): spesso si può vivere con una soluzione che funziona davvero bene nella maggior parte dei casi e accettare che a volte fallisce, purché sia ​​possibile rilevare e gestire gli errori quando si verificano.


2
I ricordi, le ipotesi e le scuse di Pat Helland trattati anche in Building on Quicksand e le transazioni compensative sono idee pertinenti qui.
Derek Elkins,

1
Hai detto "non proprio" ma sento che sei d'accordo con quello che ho suggerito. Sembra che quello che stai dicendo sia che quando l'utente sta semplicemente navigando, diamo una approssimazione cache dell'inventario rimanente, ma solo quando tentano effettivamente di completare l'acquisto facciamo la scrittura per diminuire l'inventario rimanente. Il DB che contiene quel valore eseguirà ogni transazione atomicamente e se due utenti provano contemporaneamente, mostreremo un messaggio di errore per il secondo, poiché è improbabile che ciò accada. Quindi, alla fine c'è un numero intero su una singola macchina che contiene "la verità".
mattgmg1990,

2
@ mattgmg1990: corretto, alla fine devi ovviamente conoscere "la verità" da qualche parte, ma la differenza importante è che l'elaborazione degli ordini può essere eseguita in una coda, quindi non hai bisogno di un accesso simultaneo alla scrittura atomica. Nel mio caso, il "messaggio di errore" in realtà è arrivato poche ore dopo aver completato l'ordine sul sito Web di Amazon: ho ricevuto un'email che diceva che avevano problemi con la fornitura di quell'articolo e che potevo scegliere di annullare l'ordine o non fare nulla e aspettare per loro di soddisfarlo. Ho fatto quest'ultimo poiché non avevo bisogno immediatamente dell'articolo e lo hanno effettivamente consegnato diverse settimane dopo.
Michael Borgwardt,

@DerekElkins è un ottimo articolo, in particolare il punto sui dati digitali che sono una rappresentazione della realtà che è inevitabilmente imperfetta perché la realtà può sempre avere cambiamenti che il tuo sistema non può conoscere automaticamente.
Michael Borgwardt,

6

Una combinazione di

  • hashing
  • sharding
  • replicazione
  • distribuzione
  • alto failover
  • negozi con valori-chiave

Non c'è magia, solo situazioni sempre più complesse. Proprio come il DNS, è fatto su scala.

La "versione singola della verità" fa parte di tali sistemi. La generazione di una nuova chiave diventa un'operazione più complessa rispetto alla semplice generazione del numero successivo nella sequenza. Ad esempio esistono altre sequenze. Questo è il tipo di complessità che i sistemi di database distribuiti possono gestire e lo fanno eseguendo diverse operazioni da e verso i componenti quando creano nuovi oggetti, rendendoli disponibili per gli altri, assicurando che le sequenze siano uniche quando devono essere, chiavi composte, ecc. .


Ho letto di ciascuno di questi concetti, ma la parte su cui continuo a rimanere bloccato è lo scenario specifico del rimanente inventario. Se rimangono solo 5 libri e gli utenti che fanno richieste su più server, si risolvono sempre in una singola tabella di database quando arriva il momento di interrogare l'inventario rimanente per garantire che due utenti non possano ottenere l'ultimo libro contemporaneamente? Quale uso specifico di quanto sopra sta facendo in modo che questo non rallenti l'intero sistema e la replica possa ancora essere utile con più istanze DB?
mattgmg1990,

Aggiunto un po 'di più. non riesco davvero a spiegare tutta la complessità di questo formato, mi dispiace.
Michael Durrant,

1
Solo alcune persone sono interessate a un dato libro, questo significa che il libro può essere gestito da un frammento con un carico relativamente piccolo.
Basilevs,

6
Penso che nello scenario che stai descrivendo il sistema debba solo scusarsi con l'utente che qualcun altro ha acquistato l'ultima copia. Immagino che questo accada di tanto in tanto.
Matthew James Briggs,

1
Scommetto che restano solo 5 libri che indicano meno computer e più marketing.
mouviciel,

5

Ho riscontrato il problema "Ultimo articolo disponibile" nel modo seguente:

Aggiorna tutti i livelli delle scorte quotidianamente e contrassegna i prodotti come alti, bassi, in ordine o esauriti secondo le soglie.

Ovviamente sono gli articoli 'scorte limitate' che sono problematici

  • Articoli con livelli di scorte elevati

Non preoccuparti di controllare il livello delle scorte. Basta effettuare l'ordine

  • Articoli con bassi livelli di scorte

Avvisa l'utente durante la navigazione "Ultimi rimasti!". quando vanno a pagare, controlla e diminuisci il livello delle scorte. Se esaurito, aggiorna lo stato dell'articolo.

In questo modo colpisci il database solo per gli articoli 'scorte limitate' e lo fai solo quando il cliente è abbastanza in fondo al processo di acquisto. Il costo è che alcuni clienti non saranno in grado di completare il loro acquisto.

Tuttavia, nella maggior parte dei casi "esaurito" significa solo che stai aspettando un'altra consegna, quindi vuoi comunque accettare l'ordine e magari far apparire un avviso o limitare le opzioni di consegna. Quindi quei clienti non sono persi.

Durante i periodi di carico elevato, ad esempio le vendite, potresti persino disattivare il controllo dello stock e mandare via e-mail i clienti in un secondo momento, "scusa se abbiamo esaurito X, vorresti Y"

In sostanza l'obiettivo di qualsiasi piattaforma di e-commerce non viene mai letto dal database. Servire sempre le pagine memorizzate nella cache e fare tutto sul lato client.


2

In questo video, Martin Fowler discute dei database NoSQL:

https://www.youtube.com/watch?v=qI_g07C_Q5I

Uno dei punti (da qualche parte lì dentro) è che luoghi come Amazon preferirebbero rendere felice il 99% delle persone accettando il loro ordine senza essere in grado di verificare "di sicuro" se è effettivamente disponibile e forse irritare una percentuale molto piccola avendo per dire "scusa, sembra che qualcuno ti abbia battuto."

Vale a dire, non esiste una vera gestione per lo scenario che descrivi, solo che Amazon trae vantaggio dal dubbio in base all'ultimo inventario letto correttamente e se una transazione concorrente si intrufolava tra - oopsie.

(a proposito, è un video fantastico se sei curioso di sapere su NoSQL)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.