Я бы сказал, что решение будет сильно зависеть от того, что именно вам нужно сделать. Решение для записи тысяч записей в секунду может сильно отличаться от увеличения счетчика в приведенном вами примере. Более того, не может быть tables
, чтобы справиться с такой нагрузкой. Consistency
/ availability
требования также отсутствуют в вашем вопросе, и в зависимости от них вся архитектура может сильно отличаться.
В любом случае, вернемся к вашему конкретному упрощенному случаю и вашим возможностям
Вариант 1 (репликация главного подчиненного)
Проблема, с которой вы здесь столкнетесь, - это база данных locking
- для каждого приращения потребуется блокировка записи, чтобы избежать условий гонки, и вы быстро получите свои процессы, записывающие в вашу базу данных, ожидающую в очереди, и вашу систему не работающую. Даже при умеренной нагрузке)
Вариант 2 (Sharding the DB)
Ваше предположение верно, мало чем отличается от стр.1
Вариант 3 (пакетные обновления)
Очень близко. Кэширующий слой, обеспеченный легким хранилищем, обеспечивающий одновременное атомное увеличение / уменьшение с постоянство , чтобы не потерять ваши данные. Мы использовали redis
для аналогичной цели, хотя любая другая база данных key-value также подойдет - буквально десятки таких баз данных существуют.
База данных значений ключей или хранилище значений ключей является парадигмой хранения данных.
предназначен для хранения, извлечения и управления ассоциативными массивами,
структура данных, более известная сегодня как словарь или хеш-таблица
Решение будет выглядеть следующим образом:
incoming requests → your backend server -> kv_storage (atomic increment(product_id))
И у вас будет запущен «очищающий» скрипт, т.е. */5
, который выполняет следующее (упрощенно):
- за каждые
product_id
в kv_storage читать его текущий value
- обновить свой счетчик дБ (
+= value
)
- уменьшить
value
в kv_storage
Дальнейшее масштабирование
- если скрипт завершится неудачно, ничего плохого не произойдет - обновления появятся при следующем запуске
- если ваши бэкэнд-боксы не справляются с нагрузкой - вы можете легко добавить больше ящиков
- если один db со значением ключа не может справиться с нагрузкой - большинство из них поддерживают масштабирование по нескольким блокам, или простая стратегия шардинга в ваших скриптах на сервере будет работать нормально
- если один «очищающий» сценарий не поспевает за приращениями - вы можете масштабировать их до нескольких блоков и решать, какие диапазоны ключей обрабатываются каждым