Как такая компания, как Amazon, избегает узких мест в доступе к слою базы данных?

29

Если вы представляете такую ​​компанию, как Amazon (или любое другое крупное веб-приложение для электронной коммерции), которая эксплуатирует интернет-магазин в больших масштабах и имеет лишь ограниченное количество физических товаров на своих складах, как они могут оптимизировать это так, чтобы не было одно узкое место? Конечно, у них должно быть несколько баз данных с репликацией и множество серверов, которые обрабатывают нагрузку независимо. Однако, если несколько пользователей обслуживаются отдельными серверами и оба пытаются добавить один и тот же товар в свою корзину, для которого остается только один, должен существовать некоторый «источник правды» для количества, оставшегося для этого товара. Не означает ли это, что, по крайней мере, все пользователи, имеющие доступ к информации о продукте для одного элемента, должны запрашивать одну и ту же базу данных последовательно?

Я хотел бы понять, как вы можете управлять таким большим магазином, используя распределенные вычисления, а не создавать огромное узкое место в одной БД, содержащей информацию об инвентаризации.

mattgmg1990
источник
Архитектура Amazon в середине 2000-х годов (все еще актуальна для вашего вопроса): highscalability.com/amazon-architecture
Джоери Себрехтс
Это также происходит с местами в самолетах (или, например, для упакованных праздников, когда один элемент в корзине представляет рейс там, прокат автомобиля, проживание в отеле и обратный рейс), когда много разных агентств продают одинаковые места на своих сайтах. , Решений бесчисленное множество, но все они сводятся к тому, чтобы иметь одну окончательную базу данных правды с фактическим статусом для каждой части где-то.
RemcoGerlich
1
@RemcoGerlich: то, как вы говорите «одна конечная база данных правды», заставляет меня думать об одной машине с большой священной базой данных . В действительности, что происходит с критическими данными, так это то, что все транзакции достигают нескольких серверов одновременно, обеспечивая постоянную синхронизацию всех этих баз данных.
Арсений Мурзенко

Ответы:

27

Однако, если несколько пользователей обслуживаются отдельными серверами и оба пытаются добавить один и тот же товар в свою корзину, для которого остается только один, должен существовать некоторый «источник правды» для количества, оставшегося для этого товара.

На самом деле, нет. Это не проблема, которая требует совершенного технического решения на 100%, потому что оба случая ошибок имеют бизнес-решение, которое не очень дорого:

  • Если вы неправильно сообщаете пользователю, что товар распродан, вы теряете продажу. Если вы продаете миллионы предметов каждый день, и это происходит, может быть, один или два раза в день, это теряется в шуме.
  • Если вы принимаете заказ и в процессе его обработки обнаруживаете, что у вас закончился товар, вы просто сообщаете об этом клиенту и оставляете ему возможность дождаться пополнения или отмены заказа. У вас есть один слегка раздраженный клиент. Опять же, не проблема, когда 99,99% заказов работают нормально.

На самом деле, я недавно сам столкнулся со вторым случаем, так что это не гипотетически: именно так и происходит, и как Amazon справляется с этим.

Это концепция, которая часто применяется, когда у вас есть проблема, которую теоретически очень трудно решить (будь то с точки зрения производительности, оптимизации или чего-то еще): вы часто можете жить с решением, которое действительно хорошо работает в большинстве случаев, и признать, что оно иногда сбои, если вы можете обнаружить и обработать сбои, когда они происходят.

Майкл Боргвардт
источник
2
Пат Helland - х Memories, Догадка и Извинение также покрыты в здании на Quicksand и компенсирующие сделки являются соответствующими идеями здесь.
Дерек Элкинс
1
Вы сказали "не совсем", но я чувствую, что вы согласны с тем, что я предложил. Похоже, что вы говорите, что когда пользователь только просматривает, мы даем кэшированное приближение оставшегося инвентаря, но только когда они фактически пытаются завершить покупку, мы делаем запись, чтобы уменьшить оставшийся инвентарь. БД, содержащая это значение, будет выполнять каждую транзакцию атомарно, и если два пользователя пытаются одновременно, мы показываем сообщение об ошибке для второй, так как это вряд ли произойдет. Таким образом, в конечном итоге на одной машине есть одно целое число, содержащее «правду».
mattgmg1990
2
@ mattgmg1990: правильно, в конце концов вы, конечно, должны знать «правду» где-то, но важное отличие состоит в том, что обработка заказов может быть выполнена в очереди, поэтому вам вообще не нужен одновременный атомарный доступ для записи. В моем случае «сообщение об ошибке» фактически пришло через несколько часов после того, как я завершил заказ на веб-сайте Amazon - я получил электронное письмо, в котором говорилось, что у них возникли проблемы с доставкой этого товара, и я мог отменить заказ или ничего не делать и ждать для них, чтобы выполнить это. Я сделал последнее, так как предмет мне не понадобился сразу, и они фактически доставили его через несколько недель.
Майкл Боргвардт
@DerekElkins - это отличная статья, особенно о том, что цифровые данные представляют собой представление реальности, которое неизбежно несовершенно, потому что реальность всегда может иметь изменения, о которых ваша система не может знать автоматически.
Майкл Боргвардт
6

Сочетание

  • хеширования
  • Sharding
  • копирование
  • распределение
  • высокий отказоустойчивость
  • хранилища ключей

Там нет магии, просто все более и более сложные ситуации. Так же, как DNS, он сделан в масштабе.

«Единая версия правды» является частью таких систем. Генерация нового ключа становится более сложной операцией, чем просто генерация следующего числа в последовательности. Например, существуют другие последовательности. Это та сложность, с которой могут справляться системы распределенных баз данных, и они делают это, выполняя несколько операций с компонентами при создании новых объектов, делая их доступными для других, обеспечивая уникальность последовательностей в случае необходимости, составных ключей и т. Д. ,

Майкл Даррант
источник
Я читал о каждой из этих концепций, но часть, на которой я продолжаю зацикливаться, - это особый сценарий оставшегося инвентаря. Если осталось только 5 книг, а пользователи делают запросы на нескольких серверах, всегда ли они обращаются к одной таблице базы данных, когда приходит время запросить оставшийся инвентарь, чтобы гарантировать, что два пользователя не смогут получить последнюю книгу одновременно? Какое конкретное использование вышеперечисленного делает его таким, чтобы это не замедляло всю систему, и репликация все еще может быть полезна для нескольких экземпляров БД?
mattgmg1990
Добавлено немного больше. я не могу действительно объяснить всю сложность, связанную с этим форматом, извините.
Майкл Даррант
1
Только некоторые люди интересуются любой данной книгой, это означает, что книга может обрабатываться осколком с относительно небольшой нагрузкой.
Basilevs
6
Я думаю, что в сценарии, который вы описываете, система просто должна извиниться перед пользователем, что кто-то еще купил последнюю копию. Я предполагаю, что это происходит время от времени.
Мэтью Джеймс Бриггс
1
Могу поспорить, что осталось всего 5 книг, показатель меньше вычислений и больше маркетинга.
Mouviciel
5

Я видел проблему «Последний товар на складе», решенную следующим образом:

Ежедневно обновляйте все уровни запасов и помечайте товары как высокие, низкие, категории заказов или товаров со склада в соответствии с пороговыми уровнями.

Очевидно, что это «товары со склада», которые являются проблематичными

  • Товары с высоким запасом

Не беспокойтесь о проверке уровня запасов. Просто разместите заказ

  • Товары с низким уровнем запасов

Предупредить пользователя при просмотре «Последние несколько осталось!». когда они идут, чтобы заплатить, проверьте и уменьшите уровень запаса. Если его нет в наличии, обновите статус товара.

Таким образом, вы попадаете в базу данных только для товаров с «низким запасом», и вы делаете это только тогда, когда покупатель находится в процессе покупки. Стоимость заключается в том, что некоторые клиенты не смогут завершить покупку.

Однако в большинстве случаев «нет в наличии» на самом деле означает, что вы ожидаете другую доставку, поэтому вы все равно хотите принять заказ и, возможно, просто выдать предупреждение или ограничить варианты доставки. Таким образом, эти клиенты не потеряны.

Во время высоких нагрузок, таких как продажи, вы можете даже отключить проверку запасов и просто отправить электронное письмо клиентам позже: «Извините, у нас кончился X, хотите ли вы Y»

По сути, цель любой платформы электронной коммерции никогда не читается из базы данных. Всегда обслуживайте кэшированные страницы и делайте все на стороне клиента.

Ewan
источник
2

В этом видео Мартин Фаулер обсуждает базы данных NoSQL:

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

Один из моментов (где-то там) заключается в том, что такие места, как Amazon, скорее будут радовать 99% людей, принимая их заказ, не имея возможности проверить «наверняка», действительно ли он доступен, и, возможно, раздражать очень маленький процент, имея сказать "извините, похоже, кто-то избил тебя до этого".

Иными словами, для описываемого вами сценария нет реальной обработки, просто Amazon использует выгоду от сомнений, основанных на последнем успешном прочтении инвентаря, и в случае промежуточной транзакции между ними - упс.

(кстати, это отличное видео, если вам интересно узнать о NoSQL)

jleach
источник