Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Выбираем поисковик умом головы. Андрей Аксенов

fwdays
November 18, 2014

Выбираем поисковик умом головы. Андрей Аксенов

fwdays

November 18, 2014
Tweet

More Decks by fwdays

Other Decks in Programming

Transcript

  1. Про что доклад • Надо поиск, какой взять? • Дык

    в MySQL/Postgres/Mongo/MyMegaDatabase чота встроенное типа есть и агонь • Взять Sphinx, C++ не подведёт • Взять Lucene/Solr/Elastic, Java не подведёт • Самим всё написать, мы ж мужики • Купить крутейший коммерческий, например
  2. Про что доклад • Надо поиск, какой взять? • Чем

    и как DB-built-in vs Sphinx vs Lucene vs … оно всё внутри вообще отличается? • Как правильно бенчмаркать? • Что ещё нужно сравнивать?
  3. Про что доклад • Надо поиск, какой взять? • Разумеется,

    Sphinx! • Разумеется, с контрактом на поддержку! • Разумеется, чем больше нулей, тем лучше! • Всё, доклад окончен, расходимся
  4. Самописный поиск за 1 час create table X ( keyword

    varchar(255) not null, docid integer primary key not null ); insert into X values (“hello”, 123), (“world”,123); select * from X a, X b where a.keyword=“hello” and b.keyword=“world” and a.docid=b.docid
  5. Самописный поиск за 1 вечер • Можно даже успеть вкрутить

    еще всякое! • Стеммер, libstemmer и его порты • Морфология, pyrmophy2, phpmorphy (оригинальный AOT успеть нельзя) • Ранжирование, BM25 (ну или почти) • alter table X add column termfreq integer • create table D (keyword varchar(255), docfreq integer) • select …
  6. Встроенный в базу поиск • Согласно вендору, Дичайше Круче Всех

    • На самом деле, Неизбежно Будет Говнецо * • Все базы в первую очередь про OLAP, ох • Великие Древние ещё также умеют транзакции, ууух • Типично муторно масштабировать • Синтаксис, ранжирование, эффективность? Не, не слышали (*) Разумеется, именно Ваш Любимый Вендор не такой!
  7. Самописный поиск за 10 лет • Можно успеть вкрутить ещё

    всякое!!! • Внятный формат индекса • Поддержка атрибутивки • Синтаксис запросов • Ранжирование • Кластеризация • Каждый пункт = N переделок, M лет
  8. Внешний поиск • FOSS (free, open source) • Sphinx •

    Lucene + сервера поверх (Solr, Elastic) • Коммерческие • FAST, Endeca, Autonomy, Verity… куча вендоров • Отдельный мир, обязательно Sharepoint + МегаВендор + минима 4-5 нулей • Интеграция, поддержка, функционал часто (всегда?!!) хтонические
  9. Так своё писать или как!? • Как ни странно, иногда

    надо • Core product (Google, Yandex, Bing…) • Спецтребования (“хочу взлетать в 16 KB памяти…”) • Ключевое, осознавать масштаб бедствия • У нас вот получается довольно компактно • Sphinx 0.1 = ~1K LOC, Sphinx 2.x = ~120K LOC • Больше фичей и-или “сопливый” код = ~1..10M+ LOC
  10. Так своё писать или как!? • 99%, что вам –

    не надо • Мало усилий => так себе и получится • Много усилий => это зачем? • Берите базу, берите Sphinx, берите Lucene & spawn • Бегите от “заказчиков”, у которых нету $10 на VPS!!!
  11. А чем НеСвои отличаются-то? • Ууу… отличаются метод доставки данных;

    форматы индекса; скорость индексации; размеры индекса; требования к RAM; механизмы масштабирования; API доступа; функционал текстового поиска; скорость текстового поиска, причем от вида запроса; скорость НЕтекстового поиска; добавочные функции (геопоиск, фасеты, подсказки, сниппеты); ранжирование; расширяемость…
  12. Что сравнивать? • Сравнивать надо важное • Не умеют не

    только лишь все • Мало кто может это делать • У каждого свои требования, и они ортогональны • Качество поиска VS супербыстрый булев поиск? • Текстовый поиск VS атрибутивка? • Масштабирование на терабайты VS индекс на 1 GB?
  13. Про отличия чуть подробнее • Совсем подробно нельзя – уйдет

    3 дня • Поэтому – очень кратко, по верхам • 3 категории = (1) базы, (2) FOSS, (3) commercial • 4 мегаоси = (1) эффективность, (2) функционал, (3) масштабируемость, (4) интеграция
  14. Performance Functions Scaling Integration DBMS 1..2 1..2 1..3 5+ FOSS

    (Sphinx, Lucene) 3..5 4..5 3..5 3..4 Commercial 1..5 1..5 1..5 3..4 DIY 1d..1m 1* 1* 1* 1* • Это экспертные оценки • Привычная со школы шкала от 1 до 5 • Получены методом ковыряния пальцем в носу • Нос был мой
  15. Правильно читаем таблицу • Типичная база • всегда хреновенькие скорость,

    функционал, масштабируемость… • …зато отличная интеграция! • Типичный FOSS • хорошо или отлично С/Ф/М • интеграция терпимо или хорошо (но очевидно хуже встроенного)
  16. Правильно читаем таблицу • Commercial • возможны адовые попадосы по

    любому параметру – это за свои же деньги • в целом не впечатляет • DIY • в общем (для всех задач) будет очень плохо • но в частностях, возможно, невероятно хорошо • хочешь круто угореть – спроси меня как!
  17. Sphinx vs Lucene • Поговорим немного про “а что внутри”

    • Какие сходства, откуда растут отличия • Sphinx = сервер, C++ • библиотека “как бы” есть • Lucene = библиотека, Java • Solr = сервер, Java • Elastic = сервер, Java
  18. Sphinx 2.x vs 3.x • Долго делаем, всякому научились •

    Теперь переделываем внутри много всего • Некоторые переделки Поменяют Всё, поэтому!
  19. Sphinx vs Lucene • Что одинаковое? • Идеология “инвертированный файл”

    • Всё начинается от текстового поиска • Отдельно довески про атрибутивку • Что это значит? • “Тупо поиск” работает принципально одинаково • Детали реализации, однако, могут Менять Всё
  20. Детали Меняют Всё • Пример, пока не забыл: поиск подстрок

    • Sphinx 1.x, преиндексируем всё • Sphinx 2.0, expansion с индексами • Sphinx 3.0, думаем про гибрид • Lucene ?.?, expansion без индексов • Lucene 4.?, expansion с индексами • Разница в скорости в 100 (сто) раз? Легко • Разница в памяти? Привет, “Журавлёв”
  21. Sphinx vs Lucene • Что разное внутри? • Формат хранения

    ключевиков, постингов • Формат хранения атрибутов • “Привычки” внутреннего кеширования • “Фокус” матчилки • Что это значит?
  22. Про формат постингов • Sphinx 2.x = общие словари и

    постинги • Lucene = отдельные по каждому полю • Матчинг в “редком” поле = Lucene “О-быстрее” • Матчинг по куче полей = Lucene “О-медленнее” • Матчинг с весами = Lucene “О-медленнее” • Нумерация полей = Sphinx 2.x ограничен 256 полями, индекс “О-больше” по размеру • Куча полей, куча уникальных “слов” = плохо везде, муахаха (словарь)
  23. Про формат атрибутов • Sphinx 2.x = in-memory, row-based attr

    table • Lucene = on-disk, row-based docstore + кеш • Доступ в Sphinx = in-memory hash lookup • Доступ в Lucene = как бы disk read, поэтому кеш • Sphinx = можно мешать schemaful/schemaless • Lucene = полный schemaless, поэтому кеш  • Зато в 2.x дурные legacy ограничения  • Зато у нас возможен UPDATE 
  24. Про формат документов • Lucene = хранилка документов есть •

    Sphinx 2.x = хранилки документов нет • Sphinx 3.x = хранилка документов тоже есть • Тоже перерастаем в странную СУБД • Тоже disk based, тоже LZ4 • Принципиально улучшить не удалось
  25. Про кеширование • Sphinx = запрос надо считать адово быстро

    • Sphinx = внутренних кешей почитай нет  • Lucene = скорость пох, всё закешируем!  • Lucene = кешируется ВСЁ, хрен отключишь • Делать адекватные бенчмарки это АД • Xapian (внезапно) = мега оптимизация под дефолтный, никому не нужный юзкейс
  26. Про “фокус” матчилки • Sphinx 2.x = позиции! ранжирование! релевантность!

    фиксированный бюджет памяти! • Lucene = не-не-не, булев матчинг и может BM25; памяти побольше тупо ставь • Sphinx 2.x = неидеально c булевым поиском • Sphinx 3.x = думаем про отдельный lightweight path… и убрать бюджетирование, муахахаха • Lucene = неидеально с ранкингом, позициями
  27. Что на этаж выше? • Sphinx vs Solr/Elastic, что одинаковое?

    • Везде некий API (SphinxQL, REST/XML или JSON) • Везде завелись RT индексы, schemaless/JSON • Везде агрегация результатов с кластера • Везде поддержка атрибутивки, допфункций • Везде, что странно, “просто поиск” сегодня как- то работает!!! • Коммодитизация…
  28. Что на этаж выше? • Sphinx vs Solr/Elastic, что разное?

    • S/E, репликация, автошардинг, REST, “реверсные” поиски, менеджмент кластера (почти всё тоже делаем для 3.0) • Sphinx, встроенная морфология, “сложное” ранжирование, считалка выражений • Разный “эзотерический” функционал • Sphinx, плохо помню! Zones, blend_chars, … • S/E, плохо знаю! Per-field mappings, nested docs, …
  29. Идеала нет! • Мне не нравится, как устроен Sphinx 2.x

    • Мне не нравится, как устроен Lucene • И в Sphinx 3.0 мне тоже пока (?) не всё нравится!!!
  30. Как “правильно” бенчмаркать • На оценку 3 = берем разные

    системы, делаем к ним одинаковый запрос, сравниваем время • На оценку 4 = повторяем запрос N раз, считаем среднее время, чтобы кеш прогрело и не дрожало • На оценку 5 = выкидываем 1й прогон всегда и даже выкидываем outliers, считаем среднее без них
  31. Тёплое != мягкое • Где ошибка? • “берем разные системы,

    делаем к ним одинаковый запрос”… • Одинаковый запрос •ОДИНАКОВЫЙ ЗАПРОС
  32. Marketing-driven defaults 1 • “Одинаковый запрос” очень разный • Sphinx

    defaults = strict-AND, “средний” proximity+bm15 ранкер, анализ позиций • Lucene defaults = OR (вроде!), “легкий” bm15/25 ранкер, почти булев поиск • Xapian (внезапно!) = top-N по ихнему bm25! • …и это еще цветочки!!!
  33. Marketing-driven defaults 2 • Повторные запросы? • Sphinx = честно

    считаем всё заново, кешируется только read(), и тот внутриOS • Lucene = на всех уровнях внутренние кеши, некоторые не отключить никак – Нужна долбежка многими разными запросами – Повтор 1 запроса подряд = обмеряем кеш – Повтор 10-20 запросов = в общем-то тоже
  34. Marketing-driven defaults 3 • Сниппеты, прям шедевр! – “А чё

    у вас в N раз медленнее, чем Solr?” – Sphinx, поддержка синтаксиса / Solr, тупорылый bag-of-words – Sphinx, произвольный текст / Solr, только преиндексированный – И ключевая “оптимизация” Solr... – Зачем честно подсвечивать всё, если можно быстро первые 64 KB?!
  35. Мы на горе всем буржуям • Поломаем совместимость!!! • Но

    исправим дефолты  • Учитесь на моих ошибках, кстати
  36. Идеальная Ситуация • Определяем реальные ключевые требования • Слегка изучаем

    сравниваемые системы (увы!) • Делаем действительно сходные запросы • Моделируем боевую нагрузку, помним про внутренние и внешние кеши • Смотрим функционал (что реально критично?) • Прикидываем на пальцах TCO
  37. Идеальная Ситуация • Определяем реальные ключевые требования • Слегка изучаем

    сравниваемые системы (увы!) • Делаем действительно сходные запросы • Моделируем боевую нагрузку, помним про внутренние и внешние кеши • Смотрим функционал (что реально критично?) • Прикидываем на пальцах TCO
  38. Помним Общие Моменты • База = – Забудь про функционал/скорость

    – Зато удобно (ничего не надо делать!!!) • Sphinx, Lucene et al = – Ср. быстро и функционально – Разные виды запросов могут сильно отличаться – Разный функционал и, похоже, “фокус” – Мерить нужное, иначе (уже+пока) никак
  39. Помним Общие Моменты • DIY = – Бюджетировать лучше бы

    годы – Результат может быть любой • Коммерческие = – Неожиданные подвохи везде – Хтоническая интеграция и поддержка – Шмотка +X к TCO, но зато +Y к откату • Дефолтные настройки могут удивить, везде
  40. И... делаем Правильный Выбор! • Выбираем систему X, т.к. –

    Друг Вася пользуется и Петя ещё хвалил! – На Хабре чота писали вроде крутое! – Есть интерн с опытом! (homepage) • Выбираем систему Y, т.к. – Она дорогая от известного мега-производителя – И деньги очень нужны имеет убедительные плюсы