Скачать презентацию Sphinx в примерах и задачах Андрей Аксенов Sphinx Скачать презентацию Sphinx в примерах и задачах Андрей Аксенов Sphinx

f9d456bde6af10d79d140d023d5c21ce.ppt

  • Количество слайдов: 46

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Мультизапросы $client = new Sphinx. Client (); $q = “laptop”; // coming from website Мультизапросы $client = new Sphinx. Client (); $q = “laptop”; // coming from website user $client->Set. Sort. Mode ( SPH_SORT_EXTENDED, “@weight desc”); $client->Add. Query ( $q, “products” ); $client->Set. Group. By ( SPH_GROUPBY_ATTR, “vendor_id” ); $client->Add. Query ( $q, “products” ); $client->Reset. Group. By (); $client->Set. Sort. Mode ( SPH_SORT_EXTENDED, “price asc” ); $client->Set. Limit ( 0, 10 ); $result = $client->Run. Queries ();

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

Partitioning Partitioning

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

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

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

Разбиение под CPU/HDD • Распределенный индекс, куски явно дробим по физическим устройствам • Прицеливаем Разбиение под CPU/HDD • Распределенный индекс, куски явно дробим по физическим устройствам • Прицеливаем searchd “сам на себя” – index dist 1 { type = distributed local = chunk 01 agent = localhost: 3312: chunk 02 agent = localhost: 3312: chunk 03 agent = localhost: 3312: chunk 04 }

Куем highload Куем highload

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

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

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

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

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

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

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

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

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

Три Большие Кнопки • Если ничто другое не помогает… • Cutoff (см. Set. Limits()) Три Большие Кнопки • Если ничто другое не помогает… • Cutoff (см. Set. Limits()) – Останов поиска после N первых совпадений – В каждом индексе, не суммарно • Max. Query. Time (см. Set. Max. Query. Time()) – Останов поиска после M миллисекунд – В каждом индексе, не суммарно

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

Вопросы? Вопросы?