2014-01-21 5 views
6

У меня есть несколько серверных серверов, расположенных в двух разных центрах обработки данных (в США и Европе). Эти серверы просто доставляют объявления на основе CPM.Уменьшение денежного баланса, хранящегося на главном сервере из многочисленных бэкэндов? (распределенный счетчик, а?)

У меня есть большой & хозяин жира MySQL сервер, обслуживающий денежные балансы рекламной кампании рекламодателя. Опять же, все рекламные кампании доставляются на основе CPM.

При каждом показе, полученном от любого из бэкэндов, я должен уменьшить денежный баланс рекламной кампании в соответствии с ценой показа.

Например, цена за одно впечатление - 1 цент. Бэкэнд A поставил 50 показов и уменьшит денежный баланс на 50 центов. Bed B предоставил 30 показов и уменьшит денежный баланс на 30 центов.

Таким образом, основные проблемы, как я вижу, являются:

  • Backends отбывает около 2-3K впечатлений каждых секунд. Таким образом, уменьшение денежного баланса на лету в MySQL - это не очень хорошая идея imho.

  • Основания расположены в центрах обработки данных США и ЕС. Главный сервер MySQL находится в США. Сетевая задержка может быть проблемой [бэкенд EU] < -> [мастер США]

В качестве возможных решений, которые я вижу:

  • Cassandra Использование в качестве распределенного хранения счетчика. Я постараюсь осознать это решение как можно дольше.

  • Резервирование части на деньги по бэкэнд. Например, бэкэнд A подключается к мастеру и пытается зарезервировать $ 1. Поскольку 1 доллар зарезервирован и хранится локально на бэкэнд (например, в локальном Redis), нет никакой проблемы, чтобы уменьшить его со скоростью света. Основная проблема, которую я вижу, заключается в возврате денег с сервера на главный сервер, если бэкэнд отключен от схемы доставки («отключен» от балансира). Во всяком случае, это, кажется, очень приятное решение и позволит оставаться в текущем стеке технологий.

  • Любые предложения?

UPD: одно важное дополнение. Не так важно доставлять показы объявлений с высокой точностью. Мы можем доставлять больше впечатлений, чем требовалось, но не меньше.

+0

Вы можете разделить клиентские кредиты на 2? так что у вас будет региональный кредит с половиной суммы кредитов, которые делают клиент, когда у одного из них заканчиваются кредиты, они снова делятся, пока оба не отправятся 0, ps извините, плохой английский – BrenoZan

ответ

4

Это, пожалуй, самая классическая проблема с показом рекламы/показами. Вы в основном пытаетесь уравновесить несколько целей:

  1. Некоммерческий рекламный ресурс, таким образом не делая столько денег, сколько вы могли.
  2. Неперевернутый рекламный ресурс, поэтому он предоставляется бесплатно, так как вы не можете зарядить клиента за свою ошибку.
  3. Не обслуживает показы слишком быстро, потому что обычно клиенты хотят, чтобы объявление проходило через заданный календарный период времени, и обслуживая их всех через час между 2-3 AM, делает этих клиентов недовольными и не делает им ничего хорошего.

Это сложно, потому что вы не всегда знаете, сколько показов будет доступно для данного места (поскольку это зависит от трафика), и это становится еще более сложным, если вы используете CPC вместо CPM, поскольку вы затем ввести другую непознаваемую переменную скорости кликов.

Существует не один «правильный» образца для этого, но то, что я видел, чтобы быть успешными в мои года консалтинга:

  • Лечить серверную базу данных в качестве авторитетного магазина. Разбивайте его клиентом по мере необходимости для поддержки ваших целей по масштабируемости и отказоустойчивости (ограничение возможных отключений для доли клиентов). База данных знает, что у вас есть порядок вставки рекламы, например. 1000 показов в течение 7 дней. Он периодически обновляется (от нескольких минут до часа), чтобы отразить оставшийся инвентарь и некоторые базовые статистические данные для загрузки кеша в случае потери кеша, например фактического

  • Не беспокойтесь о денежных балансах на уровне рекламного сервера. Учитывайте только количество показаний, ставки и цели. Устанавливайте это на деньги, балансируя после факта посредством регистрации и автономной обработки.

  • Закажите инвентарь из очень легкого и быстрого кеша (около веб-серверов), который кэширует оставшееся количество показов и целевую скорость доставки порядка вставки и вычисляет фактическую скорость обслуживания.

  • Зарегистрировать все сделанные показы с соответствующими данными.

  • Периодически собирайте скорости обслуживания и возвращайте их обратно в базу данных.

  • Периодически собирать журналы и рассчитать фактический обслуживаемый инвентарь и вернуть его обратно в базу данных. (Вы, возможно, потребуется произвести перерасчет из бревен из-за перебоев в подаче, ДОЗ, спам и т.д.)

2

это не может быть подробный канонический ответ, но я буду предлагать свои мысли как можно [и по крайней мере частичное] решения , Мне нужно немного догадаться, потому что вопрос не говорит о том, какие измерения были предприняты для определения узких мест mysql, которые имхо является местом для начала. я говорю, что, поскольку imho 1-2k транзакций в секунду не выходит за пределы диапазона для mysql. я легко поддерживал тома на этом высоком уровне [и намного выше] с некоторой комбинацией следующих методов: здесь нет особого порядка, потому что это зависит от того, какие измерения говорят мне об узких местах: редизайн 0-базы данных; 1-настраиваемые буферы; 2-добавление барана; 3-твердотельные накопители; 4-Sharding; 5-обновление до mysql 5.6+, если на 5.5 или ниже. поэтому я бы взял некоторые измерения и применил вышеизложенное, как это было вызвано результатами измерений. надеюсь, что это поможет.

5

Как насчет того, чтобы уменьшать баланс, вы сохраняете журнал всех сообщаемых работ из каждого бэкэнда, а затем вычисляете баланс, когда вам это нужно, вычитая сумму всей сообщаемой работы из учетной записи кампании?

Таблицы:

campaign (campaign_id, budget, ...) 
impressions (campaign_id, backend_id, count, ...) 

Отчет работы:

INSERT INTO impressions VALUES ($campaign_id, $backend_id, $served_impressions); 

Расчет баланса кампании только тогда, когда необходимо:

SELECT campaign.budget - impressions.count * $impression_price AS balance 
FROM campaign INNER JOIN impressions USING (campaign_id); 
3

Создать службу на большом сервере & жира мастер MySQL показывая денежные остатки рекламной кампании рекламодателя.

Эта служба должна реализовать getCampaignFund (idcampaign, requestingServerId, currentLocalAccountBalanceAtTheRequestingServer), который возвращает creditLimit на региональный сервер.

Представьте механизм кредитной карты. Ваш главный сервер даст некоторые ограничения вашим региональным серверам. Как только этот предел уменьшается, порог запускает этот запрос, чтобы получить новый предел. Но чтобы получить новый кредитный лимит, региональный сервер должен сообщить, сколько он использовал из предыдущего лимита.

Ваши региональные серверы могут реализовать дополнительно следующие услуги:

  1. currentLocalCampaignAccountBalance getCampaignAccountBalance (idcampaign): сообщить текущее использование конкретной кампании, поэтому главный сервер может обновлять все кампании в определенное время.
  2. addCampaign (idcampaign, initialBalance): зарегистрировать новую кампанию и начать кредитный лимит.
  3. supendCampaign (idcampaign): приостановить показ кампании .
  4. resumeCampaign (idcampaign): возобновить показ кампании.
  5. currentLocalCampaignAccountBalance finishCampaign (idcampaign): до завершает кампанию и возвращает текущий баланс локального аккаунта.
  6. currentLocalCampaignAccountBalance updateCampaignLimit (idcampaign, newCampaignLimit): обновить предел (предоставление кредита между региональными серверами). Эта услуга будет обновить кредитный лимит кампании и вернуть остаток на счете предыдущего кредитного лимита.

Услуги великолепны, поэтому у вас есть слабосвязанная архитектура. Даже если ваш основной сервер отключится в течение некоторого времени, ваши региональные серверы будут продолжать работать до тех пор, пока они не закончат свои кредитные лимиты.

1

Я полагаю,

  • Объявление, вероятно, купил в пакетах по крайней мере пары тысяч
  • Есть объявления из нескольких различных партий доставляются в то же время, не все из которых быть рядом пустуют в то же время
  • Это нормально, если вы хотите добавить дополнительную рекламу, если ваша инфраструктура не работает.

Итак, вот как бы я это сделал.

BigFat бэкенд имеет следующие методы

  • getCurrentBatches(), который будет поставлять список партий, которые могут быть использованы на некоторое время. Каждая партия содержит ставку с количеством объявлений, которые могут обслуживаться каждую секунду. Каждая партия также содержит serveMax; сколько объявлений может быть подано перед тем, как снова поговорить с BigFat.
  • deductAndGetNextRateAndMax(batchId, adsServed), который будет вычитать количество объявлений, поданных с момента последнего вызова, и вернуть новый курс (который может быть таким же) и новый serveMax.

Причина того, что курс для каждой партии заключается в том, что когда одна партия начинает бежать из средств, она будет обслуживаться меньше, пока она полностью не будет исчерпана.

Если один бэкэнд не подключается к BigFat некоторое время, он достигнет serveMax и будет показывать только объявления из других партий.

Бэкэнд может иметь отчет о секундах, минутах или даже часах в зависимости от serveMax. Совершенно новая партия с миллионами показов, оставшихся, может работать безопасно в течение долгого времени, прежде чем сообщать об этом.

Когда BigFat получает звонок в deductAndGetNextRateAndMax, он вычитает количество поданных объявлений, а затем возвращает примерно 75% от общего количества оставшихся показов до заданного макс. Это означает, что в конце партии, если она не будет заполнена, некоторые объявления будут отправлены после того, как партия будет пустой, но лучше, чтобы партия фактически была исчерпана, а не почти исчерпана в течение длительного времени.