Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Успеть за 100 миллисекунд:
контекстная реклама на Sphinx
Дмитрий Хасанов
Avito
Контекст
Требования
• 50 млн рекламных объявлений
• 300 тыс запросов в минуту
• 100 мс на ответ
Принцип работы
• отбор
• текстовый запрос
• регион
• категория
• время суток
• сортировка: bid * CTR
Модели
• десятки параметров
• миллионы коэффициентов
• обратная связь
• эксперименты, АБ-тесты
Варианты решения
• реляционная БД
• in-memory БД
• самописный инструмент
• внешний поисковый движок
Поиск в Sphinx'е
• индексация объявлений
• поиск
• ранжирование
Индексация
• БД -> TSV -> индекс
• один мастер
• разливка rsync'ом
Поиск
• запрос
• параметры окружения
• параметры пользователя
Ранжирование
• UDF для предсказания CTR
• компиляция на одной ноде
• разливка rsync'ом
UDF — user defined function
#include "sphinxudf.h"
double myudf ( SPH_UDF_INIT * init, SPH_UDF_ARGS * args, char * error_flag )
{
double res = 0;
// ...
return res;
}
int myudf_init (SPH_UDF_INIT * init, SPH_UDF_ARGS * args, char * error_message)
{
return 0;
}
void myudf_deinit ( SPH_UDF_INIT * init )
{
}
int myudf_ver ()
{
return SPH_UDF_VERSION;
}
UDF: коэффициенты внутри
postgres -> coeffs.h
#include "sphinxudf.h"
#include coeffs.h
double myudf ( SPH_UDF_INIT * init, SPH_UDF_ARGS * args, char * error_flag )
{
double result = f(coeffs);
// ...
return result;
}
...
UDF: компиляция, деплой
gcc -fPIC -shared -o ./myudf.so ./myudf.c
mysql> create function myudf returns float soname 'myudf.so';
mysql> show plugins;
+------+--------------------+------------------+-------+-------+
| Type | Name | Library | Users | Extra |
+------+--------------------+------------------+-------+-------+
| udf | myudf | myudf.so | 0 | FLOAT |
+------+--------------------+------------------+-------+-------+
UDF: вызов
mysql> select myudf(4);
+----------------+
| myudf(4) |
+----------------+
| 0.38 |
+----------------+
1 row in set (0.00 sec)
Инфраструктура
Хитрости: распределённый индекс
index adverts_distr

{
   type = distributed
   agent = server1:9312:adverts
   agent = server2:9312:adverts

}
update adverts_distr set bid=100 where id=1;
Хитрости: подзапросы
select myudf() as sort_slow
from adverts
order by sort_fast desc, sort_slow desc
limit 100
select * from (
select myudf() as sort_slow
from adverts
order by sort_fast desc
limit 100
) order by sort_slow desc
Хитрости: мультизапросы
select myudf() from adverts where foo=bar order by sort_1 asc limit 100;
select myudf() from adverts where foo=bar order by sort_2 asc limit 100;
Хитрости: индекс для атрибутов
Медленно:
select * from adverts where category_id=109;
Быстро:
select * from adverts where match('cat_109');
Хитрости: постфильтрация
• часто изменяемое
• зависит от пользователя
• не селективное
Хитрости: tmpfs
mount -t tmpfs -o size=10g tmpfs /home/sphinx/sources
Результат
SphixSearch meetup
18 июня
http://bit.ly/sphinxmeetup
Дмитрий Хасанов
pik4ez@gmail.com
github.com/pik4ez

More Related Content

"Успеть за 100 миллисекунд: контекстная реклама на Sphinx" Дмитрий Хасанов (Avito)