¿Cómo una empresa como Amazon evita los cuellos de botella al acceder a la capa de base de datos?

29

Si imagina una empresa como Amazon (o cualquier otra aplicación web de comercio electrónico grande), que opera una tienda en línea a gran escala y solo tiene una cantidad limitada de artículos físicos en sus almacenes, ¿cómo pueden optimizar esto para que no haya solo cuello de botella? Por supuesto, deben tener varias bases de datos con replicación y muchos servidores que manejan la carga de forma independiente. Sin embargo, si varios usuarios están siendo atendidos por servidores separados y ambos intentan agregar el mismo artículo a su carrito, para lo cual solo queda uno, debe haber alguna "fuente de verdad" para la cantidad que queda para ese artículo. ¿No significa esto que, como mínimo, todos los usuarios que acceden a la información del producto para un solo artículo deben consultar la misma base de datos en serie?

Me gustaría entender cómo puede operar una tienda tan grande usando computación distribuida y no crear un gran cuello de botella en un solo DB que contiene información de inventario.

mattgmg1990
fuente
Arquitectura de Amazon a mediados de la década de 2000 (aún relevante para su pregunta): highscalability.com/amazon-architecture
Joeri Sebrechts
Esto también ocurre con los asientos en los aviones (o, por ejemplo, en días festivos empaquetados donde un artículo en el carrito de compras representa un vuelo allí, un auto alquilado, una estadía en un hotel y un vuelo de regreso), con muchas agencias diferentes que venden los mismos asientos en sus respectivos sitios . Las soluciones son innumerables, pero todas se reducen a tener una base de datos de verdad final con el estado real de cada parte en alguna parte.
RemcoGerlich
1
@RemcoGerlich: la forma en que dices "una base de datos de verdad final" me hace pensar en una sola máquina con la gran base de datos sagrada . En realidad, lo que sucede con los datos críticos es que todas las transacciones llegan a varios servidores a la vez, lo que garantiza que todas esas bases de datos estén sincronizadas en todo momento.
Arseni Mourzenko

Respuestas:

27

Sin embargo, si varios usuarios están siendo atendidos por servidores separados y ambos intentan agregar el mismo artículo a su carrito, para lo cual solo queda uno, debe haber alguna "fuente de verdad" para la cantidad que queda para ese artículo.

Realmente no. Este no es un problema que requiera una solución técnica 100% perfecta, porque ambos casos de error tienen una solución comercial que no es muy costosa:

  • Si le dice incorrectamente a un usuario que un artículo está agotado, pierde una venta. Si vende millones de artículos todos los días y esto sucede tal vez una o dos veces al día, se pierde en el ruido.
  • Si acepta un pedido y, mientras lo procesa, descubre que se ha quedado sin el artículo, simplemente dígaselo al cliente y déle la opción de esperar hasta que pueda reponerlo o cancelar el pedido. Tienes un cliente un poco molesto. Nuevamente, no es un gran problema cuando el 99.99% de los pedidos funcionan bien.

De hecho, recientemente experimenté el segundo caso, así que no es hipotético: eso es lo que sucede y cómo Amazon lo maneja.

Es un concepto que se aplica a menudo cuando tiene un problema que es teóricamente muy difícil de resolver (ya sea en términos de rendimiento, optimización o lo que sea): a menudo puede vivir con una solución que funciona realmente bien en la mayoría de los casos y aceptar que a veces falla, siempre que pueda detectar y manejar las fallas cuando ocurran.

Michael Borgwardt
fuente
2
Las Memorias, las suposiciones y las disculpas de Pat Helland también cubiertas en Construir sobre arenas movedizas y las transacciones compensatorias son ideas relevantes aquí.
Derek Elkins, el
1
Dijiste "no realmente" pero siento que estás de acuerdo con lo que te sugerí. Parece que lo que está diciendo es que cuando el usuario solo está navegando, damos una aproximación en caché del inventario restante, pero solo cuando realmente intentan completar la compra, hacemos la escritura para disminuir el inventario restante. El DB que contiene ese valor ejecutará cada transacción atómicamente, y si dos usuarios intentan al mismo tiempo, mostramos un mensaje de error para el segundo, ya que es poco probable que esto suceda. Entonces, eventualmente hay un número entero en una sola máquina que contiene "la verdad".
mattgmg1990
2
@ mattgmg1990: correcto, eventualmente, por supuesto, debe saber "la verdad" en alguna parte, pero la diferencia importante es que el procesamiento de los pedidos se puede hacer en una cola, por lo que no necesita acceso simultáneo de escritura atómica. En mi caso, el "mensaje de error" en realidad llegó horas después de que terminé el pedido en el sitio web de Amazon: recibí un correo electrónico que decía que tenían problemas con el suministro de ese artículo y que podía elegir cancelar el pedido o no hacer nada y esperar para que lo cumplan. Hice lo último ya que no necesitaba el artículo de inmediato, y de hecho lo entregaron varias semanas después.
Michael Borgwardt
@DerekElkins es un gran artículo, especialmente sobre el hecho de que los datos digitales son una representación de la realidad que es inevitablemente imperfecta porque la realidad siempre puede tener cambios que su sistema no puede conocer automáticamente.
Michael Borgwardt
6

Una combinación de

  • hashing
  • fragmentación
  • replicación
  • distribución
  • alta conmutación por error
  • tiendas de valor clave

No hay magia, solo situaciones cada vez más complejas. Al igual que DNS, está hecho a escala.

La 'versión única de la verdad' es parte de tales sistemas. Generar una nueva clave se convierte en una operación más compleja que simplemente generar el siguiente número en la secuencia. Por ejemplo, existen otras secuencias. Este es el tipo de complejidad que los sistemas de bases de datos distribuidas pueden manejar y lo hacen al realizar varias operaciones hacia y desde los componentes al hacer nuevos objetos, ponerlos a disposición de otros, asegurando que las secuencias sean únicas cuando sea necesario, claves compuestas, etc. .

Michael Durrant
fuente
He leído sobre cada uno de estos conceptos, pero la parte en la que me quedo estancado es el escenario específico del inventario restante. Si solo quedan 5 libros y los usuarios que realizan solicitudes en varios servidores, ¿siempre se resuelven en una sola tabla de base de datos cuando llega el momento de consultar el inventario restante para garantizar que no haya dos usuarios que puedan obtener el último libro al mismo tiempo? ¿Qué uso específico de lo anterior hace que esto no ralentice todo el sistema y la replicación pueda ser útil con múltiples instancias de base de datos?
mattgmg1990
Agregó un poco más. Realmente no puedo explicar toda la complejidad involucrada en este formato, lo siento.
Michael Durrant
1
Solo algunas personas están interesadas en un libro dado, esto significa que el libro puede ser manejado por un fragmento con una carga relativamente pequeña.
Basilevs
66
Creo que en el escenario que está describiendo, el sistema solo tiene que disculparse con el usuario porque alguien más compró la última copia. Me imagino que esto ocurre de vez en cuando.
Matthew James Briggs
1
Apuesto a que solo quedan 5 libros, el indicador es menos computación y más marketing.
mouviciel
5

He visto el problema 'Último artículo en stock' resuelto de la siguiente manera:

Actualice todos los niveles de existencias diariamente y marque los productos como categorías alta, baja, en orden o fuera de stock de acuerdo con los niveles de umbral.

Obviamente, son los artículos de "bajo stock" los que son problemáticos

  • Artículos con altos niveles de stock

No te molestes en comprobar el nivel de existencias. Solo haz el pedido

  • Artículos con bajos niveles de existencias

Avise al usuario cuando navegue "¡Últimos pocos!". cuando van a pagar, verifique y disminuya el nivel de existencias. Si no está disponible, actualice el estado del artículo.

De esta manera, solo accede a la base de datos para los artículos de "bajo stock" y solo lo hace cuando el cliente está bastante lejos del proceso de compra. El costo es que algunos clientes no podrán completar su compra.

Sin embargo, en la mayoría de los casos, "agotado" realmente significa que está esperando otra entrega, por lo que desea aceptar el pedido de todos modos y tal vez solo aparezca una advertencia o restrinja las opciones de entrega. Entonces esos clientes no están perdidos.

Durante los tiempos de carga alta, como las ventas, incluso puede desactivar el control de existencias y enviar un correo electrónico a los clientes más tarde, 'lo siento, nos quedamos sin X, ¿le gustaría Y'?

Esencialmente, el objetivo de cualquier plataforma de comercio electrónico nunca se lee de la base de datos. Siempre sirva las páginas en caché y haga todo lo que sea del lado del cliente

Ewan
fuente
2

En este video, Martin Fowler analiza las bases de datos NoSQL:

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

Uno de los puntos (en algún lugar allí), es que lugares como Amazon prefieren mantener contento al 99% de las personas al aceptar su pedido sin poder verificar "con seguridad" si realmente está disponible, y tal vez irriten un porcentaje muy pequeño al tener para decir "lo siento, parece que alguien te ganó".

Es decir, no hay un manejo real para el escenario que describe, solo que Amazon aprovecha la duda en función de la última lectura de inventario exitosa, y si una transacción concurrente se deslizó en el medio - oopsie.

(por cierto, ese es un gran video si tienes curiosidad sobre NoSQL)

jleach
fuente