Структурирование данных

Lifeline

Новичок
Есть классическая банерная сеть.

Допустим 1М баннеров
100 кейвордов (со связями баннер - кейворды)
и 100 стран
у каждого баннера есть данные по ЦТР , кейводы и какие страны должны видеть этот баннер

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

В лоб задача очень простая: условно
select ... from banners where keyword like ...
and country = ...
and banner not in (что пользователь уже видел)
order by banner_ctr

Проблема возникает при выносе этих данных в кеш (условно мемкеш, редис и тп - не важно).

1. В лоб - собрать 100 * 100 массивов с баннерами по крону - нереально.
2. Кешить выборки из базы - слишком низкая эффективность, те при редкой стране и кейворде оно фактически не будет кешится (между запросами будет большой промежутов и данные будут экспарится)

Чувствую есть какой-то вариант индексировать один или несколько наборов данных в памяти и искать в нужной их части, но не знаю в какую сторону смотреть.

Требуется помощь сообщества в этой логической задачки.

Заранее спасибо.
 

radioheaded

PHP нуб
Обычно такие штуки решаются написанием специализированных демонов на С++. Ибо аналогичное решение на PHP по железу выйдет вам раз в 10-20 дороже. PHP максимум как фронт к демону.
 

damner2

Новичок
Lifeline
Для начала, на пхп можно написать демона (c libevent), который бы переиндексировал бы все существующие баннеры и их связи раз в n мин (раскладывал бы по массивам 100x100) ну и отдавал бы баннеры по запросам.

Сколько баннеров в секунду-то нада будет отдавать?
 

Lifeline

Новичок
damner2 скажем 500 в секунду
смотрел в сторону ноды и ерланга - но это даст выигрыш только в спавне процессов ну и вообще поточности, а тут вопрос больше в переборе
те если у нас просто массив 1М записей то пройти по каждому элементу
if (кейворд != что надо or country != что надо ) continue
это явно не оптимально

делать массивы и класть в кеш можно без проблем и по крону, демон для этого не обязательно, но 10 000 массивов генерить каждую минуту это опять как-то чувствую что-то не то :)
 

radioheaded

PHP нуб
Не надо циклом по массиву бегать, надо создать грамотный индекс и делать один запрос в него.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Шардить их по стране, как минимум. При наличии серверов в разных ДЦ для распределения по географическому принципу будет особенно выгодно. Кешировать выборку пачками по N баннеров - нашли пару десятков подходящих, начали их показывать, кончилась пачка - отработали - показываем следующую.
 

Lifeline

Новичок
radioheaded в базе индекс ? те каждый запрос в базу ползти ?

флоппик да, сейчас пытаюсь набрать статистику как меньше массивов получается ( по стране или по кейвордам ) и разбить по этому признаку , получится условно 100 массисов и это совсем реально генерить по крону

с пачками вариант хороший, но не обеспечивает плавности показа, те получится что баннер А покажется условно за 15 минут и все (соотв наплыв траффика на сайт рекламодателя и тп)
 

флоппик

promotor fidei
Команда форума
Партнер клуба
с пачками вариант хороший, но не обеспечивает плавности показа, те получится что баннер А покажется условно за 15 минут и все (соотв наплыв траффика на сайт рекламодателя и тп)
В пачку можно выбирать и число показов из пачки, да и пачки можно обрабатывать с разных серверов - разные. Т.е. бэкенд по крону готовит пачки, кого и сколько показать, фронты забирают себе по пачке каждый, и обслуживают их.
 
Сверху