W jaki sposób firma taka jak Amazon unika wąskich gardeł w dostępie do warstwy bazy danych?

29

Jeśli wyobrażasz sobie firmę taką jak Amazon (lub jakakolwiek inna duża aplikacja internetowa), która prowadzi sklep internetowy na masową skalę i ma tylko ograniczoną liczbę przedmiotów fizycznych w swoich magazynach, w jaki sposób mogą to zoptymalizować, aby nie było pojedyncze wąskie gardło? Oczywiście muszą mieć wiele baz danych z replikacją i wiele serwerów, które niezależnie obsługują obciążenie. Jeśli jednak wielu serwerów jest obsługiwanych przez oddzielne serwery i obaj próbują dodać ten sam produkt do koszyka, dla którego został tylko jeden, musi istnieć pewne „źródło prawdy” dla ilości pozostałej dla tego produktu. Czy nie oznacza to, że przynajmniej wszyscy użytkownicy uzyskujący dostęp do informacji o produkcie dla jednego elementu muszą wysyłać zapytania do tej samej bazy danych szeregowo?

Chciałbym zrozumieć, w jaki sposób możesz prowadzić tak duży sklep za pomocą przetwarzania rozproszonego, a nie tworzyć ogromnego wąskiego gardła na jednym DB zawierającym informacje o zapasach.

mattgmg1990
źródło
Architektura Amazon z połowy 2000 roku (wciąż aktualna
Joeri Sebrechts
Dzieje się tak również w przypadku miejsc w samolotach (lub np. Na zorganizowane wakacje, gdy jedna pozycja w koszyku reprezentuje lot tam, wynajęty samochód, pobyt w hotelu i lot powrotny), a wiele różnych agencji sprzedaje te same miejsca na swoich stronach . Rozwiązania są niezliczone, ale wszystkie sprowadzają się do posiadania jednej ostatecznej bazy danych prawdy z faktycznym statusem dla każdej części.
RemcoGerlich,
1
@RemcoGerlich: sposób, w jaki mówisz „jedna ostateczna baza danych prawdy”, przypomina mi jedną maszynę z dużą świętą bazą danych . W rzeczywistości dla danych krytycznych dzieje się raczej to, że wszystkie transakcje docierają do wielu serwerów jednocześnie, zapewniając synchronizację wszystkich baz danych przez cały czas.
Arseni Mourzenko,

Odpowiedzi:

27

Jeśli jednak wielu serwerów jest obsługiwanych przez oddzielne serwery i obaj próbują dodać ten sam produkt do koszyka, dla którego został tylko jeden, musi być jakieś „źródło prawdy” dla ilości pozostałej dla tego produktu.

Nie całkiem. Nie jest to problem wymagający w 100% doskonałego rozwiązania technicznego, ponieważ oba przypadki błędów mają rozwiązanie biznesowe, które nie jest bardzo drogie:

  • Jeśli niepoprawnie powiesz użytkownikowi, że produkt został wyprzedany, tracisz sprzedaż. Jeśli sprzedajesz miliony przedmiotów każdego dnia, a dzieje się to może raz lub dwa razy dziennie, gubi się w hałasie.
  • Jeśli zaakceptujesz zamówienie, a podczas przetwarzania okaże się, że skończył Ci się przedmiot, po prostu powiedz o tym klientowi i daj mu wybór, czy będzie można go uzupełnić, czy anulować zamówienie. Masz jednego lekko zirytowanego klienta. Znowu nie jest to duży problem, gdy 99,99% zamówień działa dobrze.

W rzeczywistości sam ostatnio doświadczyłem drugiego przypadku, więc nie jest to hipotetyczne: tak się dzieje i jak sobie z tym radzi Amazon.

Jest to koncepcja, która ma zastosowanie często, gdy masz problem, który teoretycznie jest bardzo trudny do rozwiązania (czy to pod względem wydajności, optymalizacji, czy cokolwiek innego): często możesz żyć z rozwiązaniem, które działa naprawdę dobrze w większości przypadków i zaakceptować, że czasami zawodzi, o ile można wykryć i obsłużyć awarie, gdy wystąpią.

Michael Borgwardt
źródło
2
Wspomnienia, domysły i przeprosiny Pata Hellanda omówione również w Budowaniu na ruchomych piaskach i transakcje kompensacyjne są tutaj istotnymi pomysłami.
Derek Elkins
1
Powiedziałeś „nie bardzo”, ale czuję, że zgadzasz się z tym, co zasugerowałem. Wygląda na to, że mówisz, że gdy użytkownik właśnie przegląda, podajemy przybliżone buforowanie pozostałych zapasów, ale tylko wtedy, gdy faktycznie próbują sfinalizować zakup, piszemy, aby zmniejszyć pozostałe zapasy. Baza danych zawierająca tę wartość wykona każdą transakcję atomowo, a jeśli dwóch użytkowników spróbuje w tym samym czasie, pokażemy komunikat o błędzie dla drugiej, ponieważ jest to mało prawdopodobne. Tak więc ostatecznie na jednej maszynie jest jedna liczba całkowita, która zawiera „prawdę”.
mattgmg1990
2
@ mattgmg1990: poprawne, w końcu oczywiście musisz gdzieś poznać „prawdę”, ale istotną różnicą jest to, że przetwarzanie zamówień może być wykonywane w kolejce, więc nie potrzebujesz w ogóle równoczesnego dostępu do zapisu atomowego. W moim przypadku „komunikat o błędzie” pojawił się kilka godzin po sfinalizowaniu zamówienia na stronie Amazon - dostałem wiadomość e-mail z informacją, że mieli problemy z dostawą tego produktu i mogłem anulować zamówienie lub nic nie robić i czekać aby oni to spełnili. Zrobiłem to drugie, ponieważ nie potrzebowałem przedmiotu od razu, a faktycznie dostarczyli go kilka tygodni później.
Michael Borgwardt,
@DerekElkins to świetny artykuł, zwłaszcza jeśli chodzi o to, że dane cyfrowe są reprezentacją rzeczywistości, która jest nieuchronnie niedoskonała, ponieważ rzeczywistość zawsze może zawierać zmiany, o których system nie może automatycznie wiedzieć.
Michael Borgwardt,
6

Kombinacją

  • mieszanie
  • odłamki
  • replikacja
  • dystrybucja
  • wysoka awaryjność
  • sklepy z kluczowymi wartościami

Nie ma magii, tylko coraz bardziej złożone sytuacje. Podobnie jak DNS, jest on skalowany.

„Jedna wersja prawdy” jest częścią takich systemów. Generowanie nowego klucza staje się bardziej złożoną operacją niż generowanie kolejnej liczby w sekwencji. Na przykład istnieją inne sekwencje. Jest to rodzaj złożoności, z którym mogą sobie poradzić rozproszone systemy baz danych. Robią to, wykonując kilka operacji do i ze składników podczas tworzenia nowych obiektów, udostępniając je innym, upewniając się, że sekwencje są unikalne, gdy są potrzebne, klucze złożone itp. .

Michael Durrant
źródło
Czytałem o każdym z tych pojęć, ale utknąłem w szczególnym scenariuszu pozostania zapasów. Jeśli pozostało tylko 5 książek, a użytkownicy zgłaszają żądania na wielu serwerach, czy zawsze rozwiązują problem z jedną tabelą bazy danych, gdy przychodzi czas na zapytanie o pozostałe zasoby, aby upewnić się, że dwóch użytkowników nie może dostać ostatniej książki w tym samym czasie? Jakie konkretne zastosowanie powyższego powoduje, że nie spowalnia to całego systemu, a replikacja może być nadal przydatna w przypadku wielu instancji DB?
mattgmg1990
Dodano trochę więcej. przepraszam, nie potrafię tak naprawdę wyjaśnić całej złożoności związanej z tym formatem.
Michael Durrant,
1
Tylko niektóre osoby są zainteresowane dowolną książką, co oznacza, że ​​książkę można obsługiwać za pomocą odłamka o stosunkowo niewielkim obciążeniu.
Basilevs,
6
Myślę, że w scenariuszu, który opisujesz, system musi przeprosić użytkownika, że ​​ktoś kupił ostatnią kopię. Wyobrażam sobie, że zdarza się to od czasu do czasu.
Matthew James Briggs,
1
Założę się, że pozostało tylko 5 książek, wskaźnik oznacza mniej obliczeń i więcej marketingu.
mouviciel
5

Widziałem problem „Ostatnia pozycja w magazynie” rozwiązany w następujący sposób:

Codziennie aktualizuj wszystkie poziomy zapasów i oznacz produkty jako wysokie, niskie, na zamówienie lub poza kategoriami zapasów zgodnie z poziomami progowymi.

Oczywiście problematyczne są „niskie zapasy”

  • Produkty o wysokim poziomie zapasów

Nie zawracaj sobie głowy sprawdzaniem poziomu zapasów. Po prostu złóż zamówienie

  • Produkty o niskim poziomie zapasów

Ostrzeż użytkownika podczas przeglądania „Ostatnich zostało!”. kiedy idą zapłacić, sprawdź i zmniejsz stan zapasów. Jeśli jest niedostępny, zaktualizuj status produktu.

W ten sposób trafiasz tylko do bazy danych produktów „z niskim stanem” i robisz to tylko wtedy, gdy klient jest na bardzo niskim poziomie procesu zakupu. Koszt jest taki, że niektórzy klienci nie będą mogli sfinalizować zakupu.

Jednak w większości przypadków „brak w magazynie” oznacza po prostu, że czekasz na kolejną dostawę, więc i tak chcesz zaakceptować zamówienie, a może po prostu wyświetlić ostrzeżenie lub ograniczyć opcje dostawy. Więc ci klienci nie są straceni.

W okresach dużego obciążenia, takich jak sprzedaż, możesz nawet wyłączyć sprawdzanie zapasów i po prostu wysłać do klientów e-mailem później „przepraszam, że skończyło nam się X, czy chciałbyś Y”

Zasadniczo cel dowolnej platformy e-commerce nigdy nie jest odczytywany z bazy danych. Zawsze wyświetlaj strony z pamięci podręcznej i rób wszystko po stronie klienta.

Ewan
źródło
2

W tym filmie Martin Fowler omawia bazy danych NoSQL:

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

Jedną z rzeczy (gdzieś tam) jest to, że miejsca takie jak Amazon wolą zadowolić 99% ludzi, przyjmując ich zamówienie bez możliwości sprawdzenia „na pewno”, czy jest ono faktycznie dostępne, a może irytują bardzo mały odsetek, mając mówiąc „przepraszam, wygląda na to, że ktoś cię pobił”.

Oznacza to, że nie ma prawdziwej obsługi opisywanego scenariusza, tylko że Amazon korzysta z wątpliwości opartych na ostatnim udanym odczytaniu spisu i jeśli równoległa transakcja wpadła pomiędzy - oopsie.

(przy okazji, to świetny film, jeśli jesteś ciekaw NoSQL)

Jleach
źródło