Лучшая практика для транзакций с большими объемами с обновлениями баланса в реальном времени
В настоящее время у меня есть база данных MySQL, которая выполняет очень большое количество транзакций. Проще говоря, это поток данных действий (клики и другие события), поступающих в режиме реального времени. Структура такова, что пользователи принадлежат дочерним компаниям, а дочерние компании принадлежат дочерним компаниям.
Мне нужно сохранить баланс кликов. Для простоты, скажем, мне нужно увеличить баланс кликов на 1 (на самом деле больше обработки в зависимости от события) для каждого - пользователя, субпартнера и аффилированного лица. В настоящее время я делаю это очень просто - как только я получаю событие, я делаю последовательные запросы в PHP - я читаю баланс пользователя, увеличиваю его на единицу и сохраняю новое значение, затем я читаю баланс субпартнера, увеличиваю и записываю, так далее.
Баланс пользователя - это самая важная метрика для меня, поэтому я хочу сохранить его в режиме реального времени, насколько это возможно. Другие показатели на уровне подчиненного и партнерского уровней менее важны, но чем ближе они к реальному времени, тем лучше, однако я думаю, что 5-минутная задержка может быть приемлемой.
По мере роста проекта он уже становится узким местом, и сейчас я смотрю на альтернативы - как изменить расчет сальдо. Я хочу убедиться, что новый дизайн сможет обрабатывать 50 миллионов событий в день. Для меня также важно не потерять ни одного события, и я фактически включаю каждый цикл изменений в баланс кликов в транзакции sql.
Некоторые вещи, которые я рассматриваю:
1 - Создайте задание cron, которое будет обновлять балансы на уровне субпартнера и партнера не в режиме реального времени, скажем, каждые 5 минут.
2 - Переместите хруст числа и обновите баланс в самой базе данных, используя хранимые процедуры. Я подумываю добавить отдельную базу данных, может, Postgress лучше подойдет для этой работы? Я пытался увидеть, если есть серьезное улучшение производительности, но Интернет, кажется, разделены по теме.
3 - Перемещение этого конкретного потока данных в нечто вроде hadoop с паркетом (или Apache Kudu?) И просто добавьте больше серверов, если это необходимо.
4 - Разделение существующей базы данных, в основном добавление отдельного сервера базы данных для каждого филиала.
Есть ли лучшие практики / технологии для этого типа задач или некоторые очевидные вещи, которые я мог бы сделать? Любая помощь очень ценится!
4 ответа
Мой совет по скоростному проглатыванию здесь. В вашем случае я собрал бы необработанную информацию в таблице пинг-понга, которую она описывает, а затем поручил другой задаче обобщить таблицу, чтобы сделать массу UPDATEs
счетчиков. Когда есть движение трафика, это становится более эффективным, таким образом не переворачиваясь.
Балансы кликов (и "Like counts") должны быть в таблице отдельно от всех связанных данных. Это помогает избежать вмешательства в другую деятельность в системе. И это, вероятно, улучшит кешируемость весов, если у вас больше данных, чем может быть кэшировано в buffer_pool.
Обратите внимание, что мой дизайн не включает в себя работу cron (кроме как "поддержание жизни"). Он обрабатывает таблицу, переворачивает таблицы, а затем возвращается к обработке - так быстро, как только может.
На вашем месте я бы внедрил Redis в памяти и увеличил бы ваши показатели. Это очень быстро и надежно. Вы также можете прочитать из этой БД. Создайте также задание cron, которое сохранит эти данные в БД MySQL.
Ваш веб-уровень обрабатывает число при получении и обработке HTTP-запроса? Если это так, то первое, что вы захотите сделать, это переместить это в очередь на обработку и асинхронно обрабатывать эти события. Я полагаю, что вы намекаете на это в своем пункте 3.
Существует много решений, и выбор одного из них выходит за рамки этого ответа, но некоторые пакеты следует учитывать:
- Gearman / PHP
- Sidekiq / Рубин
- Amazon SQS
- RabbitMQ
- NSQ
...так далее...
С точки зрения хранения это действительно зависит от того, что вы пытаетесь достичь, быстрое чтение, быстрая запись, массовое чтение, сегментирование / распространение, высокая доступность... ответ на каждый пункт указывает вам различные направления
Это звучит как отличный кандидат на Clustrix, который является заменой MySQL. Они делают что-то вроде разделения, но вместо того, чтобы помещать данные в отдельные базы данных, они разделяют их и реплицируют на узлы в одном кластере БД. Они называют это нарезкой, и БД делает это автоматически для вас. И это прозрачно для разработчиков. На нем есть документ с хорошей производительностью, который показывает, как это делается, но недостатком является то, что это масштабируемая база данных OTLP, которая может поглощать огромное количество аналитической обработки и данных в реальном времени.