Как устроен поиск
Андрей Аксенов, Sphinx
v.2.0
Поиск устроен вот так
• Сначала индексация
• Потом поиск
• Ставить, конечно, Sphinx +
мегаконтракт на поддержку
• Всё, расходимся
Поиск устроен вот так
• Индексация
– Берем документы
– Извлекаем ключевые слова
– Строим спецструктуру, FT index
• Поиск
– Берем запрос, ищем по спецструктуре
– Допобработка (where/order/group,
кластер, реранжирование, …)
Данные решают все
• FT index =
– Словарь
– Списки документов
– Списки позиций
– Формат хранения этого всего
А вот наноиндекс
• Словарь + списки документов:
Абыр => [ 123 ]
Валг => [ 123 ]
Васечкин=> [ 7, 40, 42, 1917, … ]
Вася => [ 3, 141, 592, 653, … ]
Петров => [ 1, 2, 3, 5, 8, 13, … ]
Петя => [ 2, 4, 8, 16, … ]
Данные решают все
• Элемент словаря на самом деле =
– Слово
– Указатель на документы/позиции
• Или инлайн данные
– Дополнительная метаинформация
• Или никакой
– Например,
w=“Абыр”, docoff=1234, posoff=5678,
ndocs=12, nposs=72, fieldmask=3, …
Данные решают все
• Словарь =
– Обычно сортированный вектор
• Круто хеш, но прощай, поиск подстрок
– Обычно пожат
• Абыр, Абырр, Абыррр, Абырвалг!
– Эффективно с инлайнигом
• Зачем ndocs=1 docsoff=1234, если можно
сразу docid=9876?!
– Оп, и вот сразу детали ретализации
Данные решают все
• Документы и позиции
– Всегда сортированы (иначе не пересечь)
Васечкин => [ 7, 40, 42, 1917, … ]
Вася => [ 3, 141, 592, 653, … ]
– Обычно пожаты (отдельная поднаука)
– Хранятся и отдельно и вперемешку
– Плюс спецфокусы! (Маски полей,
битмапы, плоская нумерация, итд итп)
Данные решают все
• Lucene = docids, tfs, postings
• Sphinx 2 = docids+meta, postings
• Sphinx 3 = ??? docids+postings
• Google, Yandex, … = ??? 
The fuck we care?!
• СКОРОСТЬ блин (и объем еще)
• Например,
“что” => [1,3,4,5,6,10,11,…]
varint => [1,2,1,1,1,4, 1,…] x 8 bit
gvi/pfd => [0,1,0,0,0,3, 0,…] x 0..2 bit
• Про 0 bit тащемта не шутка!(Хотя
такое щщасье случается оч редко)
Текста мало, дайте цифер
• Еще есть атрибуты
• Бывают schemaful, schemaless
• Хранить можно как угодно, все знают
– “relational”, JSON text, BSON, …
• Lucene = ФлексиТормоз!!!
– По меньшей мере, была и по дефолту
• Sphinx = АдскаяСмесь!!!
– relational + SphinxBSON
А к цифрам - еще цифер!!!
• Атрибуты можно хранить
– Тупо
– Менее тупо
• Со схемой: построчно, колоночно
• Без схемы: K-V, иерархия, сжатие
• Индексы: никаких, эмуляция, родные
А что еще (м.Строгино!!!)
• Про ранжирование
• Про сегменты и весь реалтайм
• Про еще отличия физики S vs L
• Про разницу подходов к снаряду
• Про как бенчить надо, а как будут
• Про жопки в реализациях
– Как зажигал [abc*]
• Плюс должно быть слово КЛАСТЕР
Про ранжирование
• Если не нужно, ура, булев матчинг
• Если лёгкое, BM25 (у нас +proximity)
• Простая формула, ДВЕ переменные
– TF, IDF по словам; плюс avg_doc_length
• Если тяжёлое, всё весело
– Например, 20 переменных. Или 800.
Про сегменты и весь RT
• Как устроен т.н. “реалтайм”?
(здесь короче картинка такая с лысым
писюном из Матрицы и типа гнутой
ложкой - ну хоть не дырявой, бггг)
• Его нету, есть create/merge/purge
• Sphinx еще умеет update атрибутивки
И еще про разную физику
• Sphinx vs Lucene чота волнует всех
• Концептуально все одинаково, но
• Разные форматы индекса, атрибутов
• S = общие словари, L = по полям
• S = таблица атрибутов в памяти,
L = документы на диске и кешкешкеш
• S = микс schemaful/less, L = вроде
только less
Про подходы к снаряду
– (плюс детали реализации, ага)
• S = надо все уметь быстро считать
• L = надо уметь отдавать из кеша!!!
• S = позиции, фикс RAM, итд итп
• L = ненене, булев и BM25 и кеш/RAM
• S = плохо, хрен включишь кеш
• L = плохо, хрен сделаешь бенчмарк
• Внезапно история про Xapian!!!
Про жопки в реализации
• Здесь внезапная история про [abc*] и
про старые версии – СЕГОДНЯ ВЕЗДЕ
ВСЕ НОРМАЛЬНО
• Старый Lucene жог, full scan словаря
• Старый Sphinx жог, безлимитный
expansion и “везде мелкие” буфера
Про как надо бенчить
• На оценку 3 = разные системы,
одинаковый запрос, смотрим время
• На оценку 4 = повторяем запрос N
раз, считаем среднее время, чтобы
кеш прогрело и не дрожало
• На оценку 5 = выкидываем 1й прогон
всегда и даже выкидываем outliers,
считаем среднее без них
Тёплое != мягкое
• Где ошибка?
• “берем разные системы, делаем к
ним одинаковый запрос”…
• Одинаковый запрос
•ОДИНАКОВЫЙ
ЗАПРОС, КАРЛ!
Marketing driven defaults 1
• Sphinx = типа быстрое strict-AND, зато
medium rare proximity+bm15
ранжирование
• Lucene = типа медленное OR, зато
lightweight bm25 ранжирование
• Xapian!!!
• …и это еще цветочки!!!
Marketing driven defaults 2
• Повторные запросы?
• Sphinx (*) = честно вычисляем всё
заново, кешируется только дисковое
чтение, и то у OS
• Lucene = на всех уровнях есть
внутренние кеши, некоторые
невозможно отключить никак
Marketing driven defaults 3
• Сниппеты, прям шедевр!
• “А чё у вас в N раз медленнее, чем
Solr?”
– Поддержка синтаксиса VS bag-of-words
– Произвольный текст VS только
преиндексированный
– И ключевая “оптимизация” про 64KB!
Слово КЛАСТЕР похоже…
• И тут внезапно такое м.Строгино
Итого
Вопросы?
для стеснительных:
shodan@sphinxsearch.com

Как устроен поиск / Андрей Аксенов (Sphinx)

  • 1.
  • 2.
    Поиск устроен воттак • Сначала индексация • Потом поиск • Ставить, конечно, Sphinx + мегаконтракт на поддержку • Всё, расходимся
  • 3.
    Поиск устроен воттак • Индексация – Берем документы – Извлекаем ключевые слова – Строим спецструктуру, FT index • Поиск – Берем запрос, ищем по спецструктуре – Допобработка (where/order/group, кластер, реранжирование, …)
  • 4.
    Данные решают все •FT index = – Словарь – Списки документов – Списки позиций – Формат хранения этого всего
  • 5.
    А вот наноиндекс •Словарь + списки документов: Абыр => [ 123 ] Валг => [ 123 ] Васечкин=> [ 7, 40, 42, 1917, … ] Вася => [ 3, 141, 592, 653, … ] Петров => [ 1, 2, 3, 5, 8, 13, … ] Петя => [ 2, 4, 8, 16, … ]
  • 6.
    Данные решают все •Элемент словаря на самом деле = – Слово – Указатель на документы/позиции • Или инлайн данные – Дополнительная метаинформация • Или никакой – Например, w=“Абыр”, docoff=1234, posoff=5678, ndocs=12, nposs=72, fieldmask=3, …
  • 7.
    Данные решают все •Словарь = – Обычно сортированный вектор • Круто хеш, но прощай, поиск подстрок – Обычно пожат • Абыр, Абырр, Абыррр, Абырвалг! – Эффективно с инлайнигом • Зачем ndocs=1 docsoff=1234, если можно сразу docid=9876?! – Оп, и вот сразу детали ретализации
  • 8.
    Данные решают все •Документы и позиции – Всегда сортированы (иначе не пересечь) Васечкин => [ 7, 40, 42, 1917, … ] Вася => [ 3, 141, 592, 653, … ] – Обычно пожаты (отдельная поднаука) – Хранятся и отдельно и вперемешку – Плюс спецфокусы! (Маски полей, битмапы, плоская нумерация, итд итп)
  • 9.
    Данные решают все •Lucene = docids, tfs, postings • Sphinx 2 = docids+meta, postings • Sphinx 3 = ??? docids+postings • Google, Yandex, … = ??? 
  • 10.
    The fuck wecare?! • СКОРОСТЬ блин (и объем еще) • Например, “что” => [1,3,4,5,6,10,11,…] varint => [1,2,1,1,1,4, 1,…] x 8 bit gvi/pfd => [0,1,0,0,0,3, 0,…] x 0..2 bit • Про 0 bit тащемта не шутка!(Хотя такое щщасье случается оч редко)
  • 11.
    Текста мало, дайтецифер • Еще есть атрибуты • Бывают schemaful, schemaless • Хранить можно как угодно, все знают – “relational”, JSON text, BSON, … • Lucene = ФлексиТормоз!!! – По меньшей мере, была и по дефолту • Sphinx = АдскаяСмесь!!! – relational + SphinxBSON
  • 12.
    А к цифрам- еще цифер!!! • Атрибуты можно хранить – Тупо – Менее тупо • Со схемой: построчно, колоночно • Без схемы: K-V, иерархия, сжатие • Индексы: никаких, эмуляция, родные
  • 13.
    А что еще(м.Строгино!!!) • Про ранжирование • Про сегменты и весь реалтайм • Про еще отличия физики S vs L • Про разницу подходов к снаряду • Про как бенчить надо, а как будут • Про жопки в реализациях – Как зажигал [abc*] • Плюс должно быть слово КЛАСТЕР
  • 14.
    Про ранжирование • Еслине нужно, ура, булев матчинг • Если лёгкое, BM25 (у нас +proximity) • Простая формула, ДВЕ переменные – TF, IDF по словам; плюс avg_doc_length • Если тяжёлое, всё весело – Например, 20 переменных. Или 800.
  • 15.
    Про сегменты ивесь RT • Как устроен т.н. “реалтайм”? (здесь короче картинка такая с лысым писюном из Матрицы и типа гнутой ложкой - ну хоть не дырявой, бггг) • Его нету, есть create/merge/purge • Sphinx еще умеет update атрибутивки
  • 16.
    И еще проразную физику • Sphinx vs Lucene чота волнует всех • Концептуально все одинаково, но • Разные форматы индекса, атрибутов • S = общие словари, L = по полям • S = таблица атрибутов в памяти, L = документы на диске и кешкешкеш • S = микс schemaful/less, L = вроде только less
  • 17.
    Про подходы кснаряду – (плюс детали реализации, ага) • S = надо все уметь быстро считать • L = надо уметь отдавать из кеша!!! • S = позиции, фикс RAM, итд итп • L = ненене, булев и BM25 и кеш/RAM • S = плохо, хрен включишь кеш • L = плохо, хрен сделаешь бенчмарк • Внезапно история про Xapian!!!
  • 18.
    Про жопки вреализации • Здесь внезапная история про [abc*] и про старые версии – СЕГОДНЯ ВЕЗДЕ ВСЕ НОРМАЛЬНО • Старый Lucene жог, full scan словаря • Старый Sphinx жог, безлимитный expansion и “везде мелкие” буфера
  • 19.
    Про как надобенчить • На оценку 3 = разные системы, одинаковый запрос, смотрим время • На оценку 4 = повторяем запрос N раз, считаем среднее время, чтобы кеш прогрело и не дрожало • На оценку 5 = выкидываем 1й прогон всегда и даже выкидываем outliers, считаем среднее без них
  • 21.
    Тёплое != мягкое •Где ошибка? • “берем разные системы, делаем к ним одинаковый запрос”… • Одинаковый запрос •ОДИНАКОВЫЙ ЗАПРОС, КАРЛ!
  • 22.
    Marketing driven defaults1 • Sphinx = типа быстрое strict-AND, зато medium rare proximity+bm15 ранжирование • Lucene = типа медленное OR, зато lightweight bm25 ранжирование • Xapian!!! • …и это еще цветочки!!!
  • 23.
    Marketing driven defaults2 • Повторные запросы? • Sphinx (*) = честно вычисляем всё заново, кешируется только дисковое чтение, и то у OS • Lucene = на всех уровнях есть внутренние кеши, некоторые невозможно отключить никак
  • 24.
    Marketing driven defaults3 • Сниппеты, прям шедевр! • “А чё у вас в N раз медленнее, чем Solr?” – Поддержка синтаксиса VS bag-of-words – Произвольный текст VS только преиндексированный – И ключевая “оптимизация” про 64KB!
  • 25.
    Слово КЛАСТЕР похоже… •И тут внезапно такое м.Строгино
  • 26.
  • 28.