Обновляем цену на сайте, что может пойти не так в большом интернет-магазине.
Кирилл ЕгоровМой канал: https://t.me/HeadOfWeb
Доклад для: https://t.me/php_nn
Поставщик прислал новый прайс-лист, его нужно отобразить на сайте.
Вполне типичный ход мысли:
1 Давайте закатаем обновление прайс-листа в транзакцию
Подводные камни:
▪ Если прайсы большие и их много, пойдет задержка в репликации, если система умная, может отстрелить реплику за отставание
▪ Если наличие находится в той же таблице и во время загрузки цен оно обновится, то возникнет дедлок
▪ Если наличие уменьшается в одной транзакции с заказом, заказ уходит в дедлок во время обновления
2 Давайте обновлять малыми порциями
Подводные камни:
▪ Неконсистентное состояние на сайте, товары то пропадают то появляются
▪ В одно время на сайте часть цен нового прайса часть старого, еще хуже если обновление упадет на середине
Как можно обеспечить атомарное изменение цен без deadlock
Решение с активной таблицей:
Иметь 2 таблицы с ценами и хранилище / таблицу с информацией об активной табличке, грузить в неактивную табличку, переключать после успешной загрузки, вполне работает, если прайс-лист один.
Решение с шардами:
Хранить прайс на определенном шарде / virtual bucket, при каждой загрузке лить в новый шард (перебалансировка), после заливки переключать информацию о шардах (где лежит прайс).
Наличие (сколько осталось товаров) лучше держать в отдельной таблице, если информация синхронизируется с другими системами.
Далее, если вы уже большие и взрослые, идут NoSQL, Elastic Search кластеры, ключи идемпотентности, хореографическая сага для микросервисов (с ретраем шагов) и много всего интересного, про что есть на хайлоаде.
Откуда дровишки? Льем круглосуточно порядка 60 млн SKU, это овер 10 000 прайс-листов, с частым обновлением, самый большой был 8.5 млн строк.