Задавайте вопросы, мы ответим
Вы не зашли.
Есть движок рекламной сети, который работает на одном сервере и с одной базой MySQL. За сутки в сети совершается несколько миллионов показов в связи с этим огромная нагрузка на БД и отказы сервера.
Как можно распределить нагрузку на несколько серверов?
Имеет ли смысл использовать mysql репликацию ?
Проблема в том что на каждую операцию чтения (выборка подходящих баннеров из базы (сложный JOIN запрос) при этом одно из условий чтобы у рекламодателя хватало денег на показ баннера) приходится операция записи (пишется лог показа этого баннера а так же вычитаются деньги с баланса рекламодателя, это делается сразу чтобы исключить ситуацию когда рекламодатель уйдет в минус)
Можно логи показа баннера и работу с балансом оформить внутренними процедурами на стороне mysql-сервера, а под относительно статичные операции чтения выделить реплики с доступом всех скриптов только на чтение.
Тогда возникает следующая проблема:
как сделать чтобы на репликах не выбирались баннеры за которые пользователь уже не сможет расплатиться. Если на мастер сервере его баланс уменьшится то пока это изменение дойдет то реплики может быть еще один показ на который на самом деле денег уже нет ?
И как быть когда ресурсов мастер сервера не хватит для операций записи ?
Подскажите пожалуйста возможные варианты решения этой проблемы, и как вообще масштабируют проекты где много операций записи ?
Неактивен
В вашем случае есть несколько путей:
1. подумать насколько можно упростить или закэшировать результаты сложных JOIN-запросов
2. подумать как закэшировать деньги у рекламодателя (например memcached), чтобы базу не дергать каждый раз. Можно массив остатков на балансе хранить в памяти, а в базу скидывать раз в 10 минут.
3. самое простое масштабирование - разнести рекламодателей по серверам. Например, есть N серверов. Находим остаток от деления id рекламодателя на N - это будет номер сервера. В вашем случае работа будет полностью независимой и репликация не потребуется.
Неактивен
3. самое простое масштабирование - разнести рекламодателей по серверам. Например, есть N серверов. Находим остаток от деления id рекламодателя на N - это будет номер сервера. В вашем случае работа будет полностью независимой и репликация не потребуется. написал:
Не совсем понял почему работа будет полностью не зависимой ? Например на сайте вебмастера открывается страница и скрипт должен подобрать подходящий по настройкам баннер (смотреть все баннеры у каждого рекламодателя) если они будут разнесены по разным базам как тогда искать ?
Неактивен
Да, точно, не учел это. Значит полностью разделить не получится. Репликация можно сделать по типу master-master, но в таком случае все апдейты будут дублироваться на всех машинах, что создаст повышенную нагрузку. Если же расходы рекламодателя хранить независимо на разных серверах, то будет проблема возможность перерасхода средств.
Альтернативно можно сделать так: выборку баннеров делать с одних серверов, на них только SELECT и редко общий апдейт, а баланс реколамодателей хранить на других серверах и разбить их по id. Статистику показа баннеров при этом придется хранить не там же, где сами баннеры.
Неактивен
Спасибо большое за советы, есть еще такой вариант:
1. Разделить всю базу на на несколько разбив по ID пользователя и разместить на мастер-серверах.
2. Сделать несколько слэйвов и на каждый слэйв собирать всю базу целиком с нескольких мастеров. И по ним уже делать выборку.
3. Сделать ограничение на минимальный остаток на балансе пользователя чтобы он не успел уйти в минус за время отставания реплик.
Что скажете о таком варианте ? и возможно ли с нескольких мастеров, где на каждом только часть базы, получить на реплике всю базу целиком ?
Отредактированно ch3cker (26.06.2010 15:00:34)
Неактивен
Средствами MySQL репликацию с нескольких мастеров делать нельзя. В этом случае придется делать перенос данных на слейвы вручную. Если у пользователя мало денег можно просто делать дополнительную проверку (которая ухудшит производительность, но только для этого случая).
Неактивен
Я бы еще предложил просто синхронизовать количества показов раз в сколько-то
времени. Т.е. каждая из реплик держит свое количество показов, а раз в минуту
собирает с каждой реплики данные и обновляет статистику на мастере. Не думаю,
что Вы обанкротитесь, если в течение минуты будете показывать бесплатные
баннеры
Неактивен