Счётчики в многопоточной среде
Не в первый раз задумываюсь о том, как организовать обработку счётчиков в системе управления рекламой. Сейчас я попытаюсь систематизировать свои мысли в этой области.
Я вижу два подхода к решению задачи хранения счётчиков. Первый подход — это хранение относительного количества показов, кликов и т.п., которые были совершены с некоторого момента времени (например, с последнего перечитывания данных из базы данных). Второй подход — это хранение абсолютного количества показов, кликов и т.п., которы были совершены за всё время. Рассмотрим эти подходы подробнее.
В случае хранения онтосительных счётчиков, предполагается, что данные по баннерам, сайтам и т.п. начитываются из хранилища (базы данных) с некоторой периодичностью. При этом мы начитываем из хранилища относительные ограничения по показам, кликам и т.п., а счётчики инициализируем в нулевое значение. Например, если у нас стоит ограничение в 1000 показов в день, а текущее показание счётчика 600, то мы получаем относительное ограничение в 400 показов.
Проблемы со счётчиками начинаются в момент, когда мы должны обновить данные. Если мы просто, последовательно сбросим показания счётчиков в хранилище, в потом считаем данные, мы наверняка потеряем те показания счётчиков, которые изменились с момента сброса до момента чтения. Как с этим бороться?
Одно из решений, которое я вижу — это обновление в три хода. Первый ход — сброс показаний счётчиков в хранилище. Второй ход — начитывание данных из хранилища, ротация данных (система начинает работать с новыми данными). Третий ход — сброс показаний счётчиков из старых данных в хранилище и атомарное увеличение показаний счётчиков в новах данных для тех объектов, для которых показания счётчиков больше нуля. В этом случае у нас данные не теряются, но возникает другая проблема — перекрут. Например, на первом этапе у нас ограничение 100, в показание счётчика 98. За время второго хода у нас совершилось ещё два показа, и счётчик принял значение в 100 показов, но из базы мы начитали ограничение в 2 показа (100-98). До момента обновления счётчика на третьем этапе мы сделали ещё два показа и, в результате, имеем 4 показа при ограничении в 2 показа. Как с этим бороться я пока не придумал
При использовании абсолютных показателей счётчиков, мы избавимся от перекрута и необходимости перечетивыть данные из базы с заданной периодичностью. Перекрута не будет потому, что мы всегда будем знать сколько совершено показов/кликов и каковы текущие ограничения. А данные можно не перечитывать полностью, для всех объектов в системе, а только те данные, которые изменились с последнего обновления.
Мой выбор, абсолютные счётчики
Tags: крутилка, оптимизация, программирование


