Como uma empresa como a Amazon evita gargalos ao acessar a camada de banco de dados?


29

Se você imagina uma empresa como a Amazon (ou qualquer outro aplicativo Web de comércio eletrônico), que opera uma loja on-line em grande escala e possui apenas uma quantidade limitada de itens físicos em seus armazéns, como eles podem otimizar isso, de modo que não haja gargalo único? Obviamente, eles devem ter vários bancos de dados com replicação e muitos servidores que lidam com a carga de maneira independente. No entanto, se vários usuários estiverem sendo atendidos por servidores separados e ambos tentarem adicionar o mesmo item ao carrinho, para o qual resta apenas um, deve haver alguma "fonte de verdade" para a quantidade restante para esse item. Isso não significa que, no mínimo, todos os usuários que acessam informações do produto para um único item devem consultar o mesmo banco de dados em série?

Gostaria de entender como você pode operar uma loja tão grande usando computação distribuída e não criar um grande gargalo em um único banco de dados que contém informações de inventário.


Arquitetura Amazon em meados de 2000 da (ainda relevantes para a sua pergunta): highscalability.com/amazon-architecture
Joeri Sebrechts

Isso também acontece com assentos em aviões (ou, por exemplo, férias em pacote, em que um item do carrinho de compras representa um voo para lá, um carro alugado, uma estadia em hotel e um voo de volta), com muitas agências diferentes vendendo os mesmos assentos em seus respectivos sites . As soluções são inúmeras, mas todas se resumem a ter um banco de dados verdade final com o status real de cada parte em algum lugar.
RemcoGerlich 12/12

1
@RemcoGerlich: a maneira como você diz "um banco de dados da verdade final" me faz pensar em uma única máquina com o grande banco de dados sagrado . Na realidade, o que acontece com dados críticos é que todas as transações atingem vários servidores ao mesmo tempo, garantindo que todos esses bancos de dados estejam sincronizados o tempo todo.
Arseni Mourzenko

Respostas:


27

No entanto, se vários usuários estiverem sendo atendidos por servidores separados e ambos tentarem adicionar o mesmo item ao carrinho, para o qual resta apenas um, deve haver alguma "fonte de verdade" para a quantidade restante para esse item.

Na verdade não. Este não é um problema que exija uma solução técnica 100% perfeita, porque os dois casos de erro têm uma solução comercial que não é muito cara:

  • Se você informar incorretamente a um usuário que um item está esgotado, você perderá uma venda. Se você vende milhões de itens todos os dias e isso acontece talvez uma ou duas vezes por dia, isso se perde no barulho.
  • Se você aceitar um pedido e, durante o processamento, descobrir que o item ficou sem estoque, basta informar o cliente e dar a ele a opção de aguardar até que você possa reabastecer ou cancelar o pedido. Você tem um cliente um pouco irritado. Novamente, não é um problema enorme quando 99,99% dos pedidos funcionam bem.

De fato, recentemente experimentei o segundo caso, então não é hipotético: é isso que acontece e como a Amazon lida com isso.

É um conceito que se aplica frequentemente quando você tem um problema que é teoricamente muito difícil de resolver (seja em termos de desempenho, otimização ou qualquer outra coisa): geralmente você pode viver com uma solução que funciona muito bem na maioria dos casos e aceitar que às vezes falhar, desde que você possa detectar e lidar com as falhas quando elas ocorrerem.


2
Memórias, palpites e desculpas de Pat Helland também abordadas em Construindo na areia movediça e transações compensatórias são idéias relevantes aqui.
Derek Elkins

1
Você disse "não realmente", mas eu sinto que você está concordando com o que eu sugeri. Parece que o que você está dizendo é que, quando o usuário está apenas navegando, fornecemos uma aproximação em cache do estoque restante, mas somente quando eles realmente tentam concluir a compra é que fazemos a gravação para diminuir o estoque restante. O banco de dados que contém esse valor executará cada transação atomicamente e, se dois usuários tentarem ao mesmo tempo, mostramos uma mensagem de erro para o segundo, pois é improvável que isso aconteça. Portanto, eventualmente, há um número inteiro em uma única máquina que contém "a verdade".
mattgmg1990

2
@ mattgmg1990: correto, eventualmente, é claro que você precisa conhecer a "verdade" em algum lugar, mas a diferença importante é que o processamento de pedidos pode ser feito em uma fila para que você não precise de acesso atômico de gravação simultâneo. No meu caso, a "mensagem de erro" realmente chegou horas depois que eu terminei o pedido no site da Amazon - recebi um e-mail informando que eles tinham problemas com o fornecimento desse item e eu poderia optar por cancelar o pedido ou não fazer nada e esperar para eles cumpri-lo. Eu fiz o último, já que não precisava do item imediatamente, e eles o entregaram várias semanas depois.
Michael Borgwardt

@DerekElkins é um ótimo artigo, especialmente o ponto sobre dados digitais serem uma representação da realidade inevitavelmente imperfeita, porque a realidade sempre pode ter alterações que o seu sistema não pode conhecer automaticamente.
Michael Borgwardt

6

Uma combinação de

  • hash
  • sharding
  • replicação
  • distribuição
  • alto failover
  • lojas de valores-chave

Não há mágica, apenas situações cada vez mais complexas. Assim como o DNS, ele é feito em escala.

A 'versão única da verdade' faz parte de tais sistemas. Gerar uma nova chave se torna uma operação mais complexa do que apenas gerar o próximo número na sequência. Por exemplo, existem outras sequências. Esse é o tipo de complexidade com que os sistemas de banco de dados distribuídos podem lidar e o fazem executando várias operações de e para componentes ao criar novos objetos, tornando-os disponíveis para outros, garantindo que as seqüências sejam únicas quando precisam, chaves compostas, etc. .


Eu li sobre cada um desses conceitos, mas a parte em que fico preso é o cenário específico do estoque restante. Se restarem apenas 5 livros e os usuários fizerem solicitações em vários servidores, eles sempre resolverão uma única tabela de banco de dados quando chegar a hora de consultar o inventário restante para garantir que dois usuários não possam obter o último livro ao mesmo tempo? Que uso específico das opções acima está fazendo com que isso não diminua a velocidade do sistema inteiro e a replicação ainda pode ser útil com várias instâncias de banco de dados?
mattgmg1990

Adicionado um pouco mais. Eu realmente não posso explicar toda a complexidade envolvida neste formato, desculpe.
Michael Durrant 12/12

1
Somente algumas pessoas estão interessadas no livro, isso significa que o livro pode ser manuseado por um fragmento com carga relativamente pequena.
Basilevs

6
Acho que no cenário em que você está descrevendo o sistema, basta pedir desculpas ao usuário pelo fato de alguém ter comprado a última cópia. Eu imagino que isso ocorra de tempos em tempos.
Matthew James Briggs

1
Aposto que há apenas 5 livros restantes, o indicador é menos computacional e mais marketing.
Mouviciel 12/12

5

Vi o problema 'Último item em estoque' resolvido da seguinte maneira:

Atualize todos os níveis de estoque diariamente e sinalize os produtos para categorias alta, baixa, no pedido ou fora de estoque, de acordo com os níveis limite.

Obviamente, são os itens de 'baixo estoque' que são problemáticos

  • Itens com altos níveis de estoque

Não se preocupe em verificar o nível de estoque. Basta fazer o pedido

  • Itens com baixos níveis de estoque

Avise o usuário ao navegar em "Últimos poucos que restam!". Quando pagar, verifique e diminua o nível do estoque. Se estiver esgotado, atualize o status do item.

Dessa forma, você só acessa o banco de dados para os itens de 'estoque baixo' e o faz apenas quando o cliente está bastante adiantado no processo de compra. O custo é que alguns clientes não poderão concluir sua compra.

No entanto, na maioria dos casos, 'estoque esgotado' significa realmente que você está aguardando outra entrega; portanto, você deseja aceitar o pedido de qualquer maneira e talvez apenas exibir um aviso ou restringir as opções de entrega. Portanto, esses clientes não estão perdidos.

Durante tempos de carregamento altos, como vendas, você pode até desativar a verificação de estoque e enviar um e-mail aos clientes mais tarde: 'desculpe, ficamos sem X, gostaria de Y'?

Essencialmente, o objetivo de qualquer plataforma de comércio eletrônico nunca é lido no banco de dados. Sempre sirva páginas em cache e faça tudo do lado do cliente.


2

Neste vídeo, Martin Fowler discute os bancos de dados NoSQL:

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

Um dos pontos (em algum lugar) é que lugares como a Amazon preferem manter 99% das pessoas felizes aceitando seu pedido sem poder verificar "com certeza" se ele está realmente disponível e talvez irritar uma porcentagem muito pequena por ter para dizer "desculpe, parece que alguém venceu você".

Ou seja, não há tratamento real para o cenário que você descreve, apenas que a Amazon tira proveito da dúvida com base na última leitura bem-sucedida do inventário e se uma transação simultânea se esvair entre oopsie.

(btw, esse é um ótimo vídeo se você estiver curioso sobre o NoSQL)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.