Здравствуйте, jazzer, Вы писали:
WH>>>Если их нет, то как идёт обработка ситуации что одного из нескольких товаров не оказалось на складе?
C>>Такого не допускается. Счётчики товара строго транзакционны. То как оно обеспечивается — отдельная и длинная история.
J>рассказывай
Счётчики разделены между шардами, при этом каждый шард получает квоту на запись. Т.е. если у нас 10000 разрешений (скажем, товаров на складе) и 5 шардов, то каждый шард может автономно выдать 2000 разрешений.
Текущее общее значение оставшихся разрешений — eventually consistent и неспешно синхронизируется между шардами.
Естественно, при низких значениях доступных разрешений нужна особая обработка — в опустевшие шарды добавляется "перенаправление" на шарды с ещё оставшимися разрешениями. Там тоже интересный алгоритм, который этим занимается.
Сами счётчики организованы как множества транзакций. Т.е. операция "взять разрешение" выглядит как "записать ID операции в множество завершённые_операции и уменьшить значение счётчика, если ID операции не в множестве завершённые_операции и счётчик больше нуля". Это гарантирует идемпотентность операции, её можно повторять произвольное число раз. Соответственно, откат выглядит как обратная операция и он тоже идемпотентный.
Когда транзакция полностью завершена, ID операции убирается из множества "завершённые_операции". ID операции так же состоит из времени начала операции и уникального случайного 64-битного числа, так что специальная задача (reconciler) в фоновом режиме сканирует все счётчики и вычищает транзакции, которые длятся слишком долго.
Ещё есть очень интересная оптимизация — идемпотентные операции можно безопасно группировать, что невозможно с классическими транзакциями. Так что когда шард получает запрос, он не выполняет его сразу же, а кладёт в очередь и начинает ждать ответа. И каждые 10-20 миллисекунд накопившиеся в очереди запросы всей пачкой выполняются, и результаты отдаются ждущим клиентам. Таким образом, количество операций получается ограничено интервалом времени, при сбросе значений каждые 20 мс. у нас всего 50 операций записи в секунду.
Это так по верхам, самые интересные части.