Sphinx в примерах и задачах Андрей Аксенов Sphinx Technologies Андрей Аксенов Sphinx Technologies.

Презентация:



Advertisements
Похожие презентации
Загадки Sphinx-а Анатомический атлас поискового движка.
Advertisements

Sphinx и его применения для поиска в БД Андрей Аксенов
Очевидное – невероятное (Sphinx tips-n-tricks) Андрей Аксенов, 2008.
Эффективный полнотекстовый поиск по базам данных Андрей Аксенов, Петр Зайцев Percona Ltd. shodan (at) shodan.ru.
Поисковые движки. Sphinx Search Engine. Докладчик: Роман Кудлай
Использование MySQL в сервисе дневников LiveInternet.ru Практика, практика, практика Гурьянов Андрей, программист Новиков Лев, системный администратор.
Что клиенты просят доделать после партнеров Евгений Потапов ITSumma.
Как улучшить производительность проекта за три шага Шаромов Денис руководитель отдела техподдержки.
Оптимизация MySQL Петр Зайцев Директор, Percona Ltd.
Поиск информации Задача поиска: где в заданной совокупности данных находится элемент, обладающий заданным свойством? Большинство задач поиска сводится.
Как Map/Reduce спас Яндекс.Статистику. Background Взрывной рост объема данных, за 8 лет объем дневных данных вырос в 2000 раз с 2ГБ до 4ТБ Скорости процессоров,
Разработка системы информационного поиска в базе знаний Белякова Д.Ю. Группа С-105 МИЭМ
Поиск на своем сайте, обзор open source решений Олег Бунин.
Резервное копирование ONLINE с ООО «ЗабЦВИТ». Зачем вам резервное копирование? Информация - это жизнь вашей компании. 43% компаний, потерявших критически.
Распределенная Архитектура LAMP приложений Петр Зайцев Директор, Percona Ltd.
Об одном алгоритме вычисления функции распределения выплат в модели коллективных страховых рисков Бацын М.В. Калягин В.А., д.ф-м.н., профессор, декан факультета.
Содержание: 1. Управление данными. а) Извлечение данных команда SELECT; б) Полный список разделов. 2. Раздел SELECT. а) Синтаксис раздела SELECT; б) Ключевые.
Гео-кластерные системы Просто и надёжно!
Ашманов и Партнеры Оценка качества и результатов поискового продвижения Мастер-класс Привлечение аудитории РИФ апреля 2008 года Андрей Кузьменков,
Построение поисковых индексов Автор: Елисафенко М.Е. гр
Транксрипт:

Sphinx в примерах и задачах Андрей Аксенов Sphinx Technologies Андрей Аксенов Sphinx Technologies

Что за… Sphinx? Sphinx – это полнотекстовый поисковик

Что за… Sphinx? Sphinx – это полнотекстовый поисковик Может копать –Активный, ответственный работник Может не копать –Внимателен к инициативам начальства Может лопату спрятать –Отличный командный игрок

Что за… Sphinx? Может то, чего по слухам не может! –«Полуживые» обновления индекса –Фасеточный поиск –Особенные, уличные SQL запросы –Геопоиск –Создание сниппетов –Мультизапросы –И еще других интересных фичей

Где выход и когда обед? О чем вы НЕ узнаете из доклада? –Зачем всё это –Что написано в документации –Что написано в исходниках О чем поговорим –Как Sphinx устроен внутри –Как оптимизировать разное –Как куют highload

Общее устройство Нет… никакого… Сфинкса.

Общее устройство Есть две программы –Indexer – строит индексы –Searchd – отвечает на запросы Еще есть API –Клиент, который умеет говорить с searchd по сети –PHP, PECL, Python, Perl, Java, Ruby, C99, C++, Haskell, C#, MySQL SE…

Как работает indexer Есть источники данных –Откуда брать (MySQL, PgSQL, xmlpipe) –Что брать (sql_query, sql_attr_xxx) –Как брать (sql_query_pre, sql_query_post) Есть физические индексы –Как индексировать (токенизация, стемминг, словоформы, HTML stripper) –Куда класть файлы

Что хранится в индексе Индекс для полнотекстовых запросов –Словарь –Списки документов по ключевым словам –Списки позиций по документам Привязанные атрибуты документов –Integer (от 1 до 32 или 64 бит) –Float –MVA (сортированный список 32-битных целых) НЕ хранятся исходные текстовые данные

Как работает searchd Получает запрос, вычисляет ответ Умеет агрегировать ответы –По нескольким физически индексам –С ответами от удаленных searchd Еще умеет строить сниппеты Еще умеет обновлять атрибуты (иногда)

Как все перестает работать

Нагрузка ударяет в спину Виды проблем –Bandwidth – слишком много запросов –Latency – слишком долгий отклик –Availability – слишком мало (работающих) серверов Как бороться? –Локально – как оптимизировать запросы –Глобально – как обустраивать кластера

Оптимизируем запросы Как работает поиск

Для каждого локального индекса –Строим список кандидатов (документов, удовлетворяющих запросу) –Фильтруем (аналог – WHERE) –Ранжируем (считаем веса документов) –Сортируем (аналог – ORDER BY) –Группируем (аналог – GROUP BY) Склеиваем результаты по всем индексам

Цена булева поиска Построение списка кандидатов –1 ключевое слово = 1+ IO (список документов) –Булевы операции над списками документов –Стоимость пропорциональна (~) длине списков –То есть, сумме частот всех ключевых слов –При поиске фраз итп, еще и операции над списками позиций слов – примерно 2x IO/CPU Мораль –The Who – очень плохая музыка –Гамлет – очень плохая литература

Цена фильтрации docinfo=inline –Атрибуты хранятся в списке документов –ВСЕ значения дублируются МНОГО раз! –Доступны сразу после чтения с диска docinfo=extern –Атрибуты хранятся в отдельном списке (файле) –Полностью кэшируются в RAM –Хэш по docid + бинарный поиск Перебор фильтров Cтоимость ~ числу кандидатов и фильтров

Цена ранжирования Прямая - зависит от ranker-а –Учитывать позиции слов - Полезно для релевантности Но стоит ресурсов - двойной удар! Стоимость ~ числу результатов Самый дорогой - phrase proximity + BM25 Самый дешевый - none (weight=1) Косвенная - может наводиться в сортировке

Цена сортировки Стоимость ~ числу результатов Еще зависит от критерия сортировки (документы придут в asc) Еще зависит от max_matches Чем больше max, тем хуже серверу 1-10K приемлемо, 100K перебор недобор

Цена группировки Группировка внутри – особый подвид сортировки Тоже число результатов Тоже max_matches Вдобавок, от max_matches зависит

(Некоторые) оптимизации

Режимы ранжирования и сортировки Фильтры против ключевых слов Мультизапросы (multi queries) Разбиение данных (partitioning) Последняя линия защиты – Три Большие Кнопки

Ранжирование… Бывает разное, см. SetRankingMode() По умолчанию – phrase+BM25 –Анализирует позиции слов –Что не бесплатно! Иногда достаточно более простого Иногда достаточно тривиального –ищем ipod, сортируем по цене…

…и сортировка Можно упростить ранжирование –Когда сортируем по цене, вес не интересен Можно вкомпилировать –См. src/sphinxcustomsort.inl Можно оптимизировать –Документы приходят в asc asc => date asc – оптимально asc => date desc – можно поменять id

Фильтры против спецслов Известный трюк –При индексации, добавляем специальное ключевое слово в документ (_authorid123) –При поиске, добавляем его в запрос Понятный вопрос –Что быстрее, как лучше? Нехитрый ответ –Считайте ценник, не отходя от кассы

Фильтры против спецслов Цена булева поиска ~ частотам слов Цена фильтрации ~ числу кандидатов Поиск – CPU+IO, фильтр – только CPU Частота спецслова = селективности значения фильтра Частое знач-е + мало кандидатов плохо! Редкое знач-е + много кандидатов хорошо!

Мультизапросы Любые запросы можно передать пачкой Всегда экономит network roundtrip Иногда может сработать оптимизатор Особо важный и нужный случай – разные режимы сортировки группировки 2x+ оптимизация фасеточного поиска

Мультизапросы $client = new SphinxClient (); $q = laptop; // coming from website user $client->SetSortMode ( desc); $client->AddQuery ( $q, products ); $client->SetGroupBy ( SPH_GROUPBY_ATTR, vendor_id ); $client->AddQuery ( $q, products ); $client->ResetGroupBy (); $client->SetSortMode ( SPH_SORT_EXTENDED, price asc ); $client->SetLimit ( 0, 10 ); $result = $client->RunQueries ();

(Некоторые) оптимизации Режимы ранжирования и сортировки Фильтры против ключевых слов Мультизапросы (multi queries) Разбиение данных (partitioning) Последняя линия защиты – Три Большие Кнопки

Partitioning

Алгоритм решения боевых задач им. тов. Цезаря Уперлось в переиндексацию? –Разбиваем, переиндексируем только изменения Уперлось в фильтрацию? –Разбиваем, ищем только по нужным индексам Уперлось в CPU/HDD? –Разбиваем, разносим по разным cores/HDDs/boxes

Разбиение под индексацию Необходимо держать баланс Не добьешь – будет тормозить индексация Перебьешь – будет тормозить поиск 1-10 индексов – работают разумно Некоторых устраивает и 50+ ( ) Некоторых устраивает и (!!!)

Разбиение под фильтрацию Полностью, на 100% зависит от статистики боевых запросов –Анализируйте свои личные боевые логи –Добавляйте комментарии (Query(), 3 rd arg) Оправдано только при существенном уменьшении обрабатываемых данных –Для документов за последнюю неделю – да –Для англоязычных запросов – нет (!)

Разбиение под CPU/HDD Распределенный индекс, куски явно дробим по физическим устройствам Прицеливаем searchd сам на себя – index dist1 { type = distributed local = chunk01 agent = localhost:3312:chunk02 agent = localhost:3312:chunk03 agent = localhost:3312:chunk04 }

Куем highload

Или «как нам обустроить кластер» Всегда будет рост bandwidth Всегда будет no-SPoF (те. «какой-то» HA) Варианты строго зависят от требований –Допустимая задержка индексации? –Допустимая скорость запроса? –Время восстановления после hard crash? –Приемлема ли деградация результатов?

Методы борьбы Борем задержку индексации –Дельта-индекс –Каскады дельта-индексов –Merge –Partitioning на несколько машин Борем скорость запроса –Оптимизируем локальные запросы –Partitioning на несколько машин

Методы partitioning Линейная репликация –Клонируем весь индекс много раз –Опционально выносим индексацию –Pro – легко поддерживать/наращивать –Pro – автоматом HA (сплошные hotspare!) –Pro – деградация невозможна –Contra – растет только bandwidth

Методы partitioning Линейный или деревянный partitioning –Разбиваем индекс на независимые куски –Линейный – star topology –Деревянный – star-of-stars topology –Pro – легко поддерживать –Pro – почти линейно падает latency –Contra – переделки при наращивании –Contra – нету HA, деградация при сбоях

Методы partitioning Комбинированные схемы –Partitioning + репликация кусков –Балансировка между конечными кусками – внешним LB (пока?), на уровне TCP port –Pro – решает все задачи –Contra – сложнее всего разворачивать и поддерживать

Военные хитрости Несколько копий searchd на сервер –Улучшает время запуска –Нужно, когда МНОГО атрибутов Raw HDD, а не RAID –Явное разделение – лучше неявного –Иначе – IO stepping для одного (!) запроса Вечный indexer –Бесконечный цикл вместо crontab

Выбираем железо Большие коллекции упираются в IO –Добивать HDD, причем числом! –Добивать RAM Маленькие коллекции в CPU Три стандартных средства –vmstat – чем и насколько занят CPU? –oprofile – кем конкретно занят CPU? –iostat – насколько занят HDD? Плюс логи, плюс опция searchd --iostats

Выбираем железо Анализируем результаты –Обычно все наглядно (us/sy/bi/bo…), но! –Ловушка – HDD может упираться в iops –Ловушка – CPU может прятаться в sy –Ловушка – «незаметные» проблемы в us

(Некоторые) оптимизации Режимы ранжирования и сортировки Фильтры против ключевых слов Мультизапросы (multi queries) Разбиение данных (partitioning) Последняя линия защиты – Три Большие Кнопки

Если ничто другое не помогает… Cutoff (см. SetLimits()) –Останов поиска после N первых совпадений –В каждом индексе, не суммарно MaxQueryTime (см. SetMaxQueryTime()) –Останов поиска после M миллисекунд –В каждом индексе, не суммарно

Три Большие Кнопки Если ничто другое не помогает… Consulting –Можем заметить незамеченное –Можем дописать недописанное

Вопросы?