blog-post

Manticore Search: 3 года после форка от Sphinx

В мае 2017 года мы сделали форк Sphinxsearch 2.3.2, который мы назвали Manticore Search . Ниже вы найдете краткий отчет о Manticore Search как форке Sphinx и наших достижениях с тех пор.

Почему мы сделали форк Sphinx?


Прежде всего, почему мы сделали форк? В конце 2016 года работа над Sphinxsearch была приостановлена. Пользователи, которые использовали Sphinx, и некоторые клиенты, поддерживавшие разработку проекта, были обеспокоены этим, потому что:

  • ошибки не исправлялись в течение длительных периодов времени
  • новые функции, которые давно обещали, не были реализованы
  • связь с командой Sphinx была нарушена

Через несколько месяцев ситуация не изменилась, и в середине июня 2017 года группа проактивных и опытных пользователей Sphinx и клиентов поддержки собралась и решила попытаться сохранить продукт в качестве форка под названием Manticore Search. Нам удалось собрать обратно большую часть предыдущей команды Sphinx, которая уже работала в разных компаниях, привлечь инвестиции и в короткие сроки восстановить полноценную работу над проектом.

Каковы были наши цели?


Форк ставил перед собой три цели:

  1. Поддержка кода в целом: исправление ошибок, небольшие и большие новые функции
  2. Поддержка пользователей Sphinx и Manticore
  3. Более интенсивная разработка продукта, чем это было ранее. К сожалению, к тому времени Elasticsearch уже обогнал Sphinx во многих отношениях.

Такие вещи, как:

  • отсутствие репликации
  • отсутствие авто id
  • отсутствие JSON интерфейса
  • отсутствие возможности создавать/удалять индекс на лету
  • отсутствие хранения документов
  • незрелые индексы в реальном времени
  • фокус на полнотекстовом поиске, а не на поиске в целом

сделали Sphinx очень специализированным решением с необходимостью вручную настраивать его во многих случаях. К тому времени многие пользователи уже мигрировали на Elasticsearch. Это было прискорбно, потому что фундаментальные структуры данных и алгоритмы в Sphinx потенциально и на самом деле во многих случаях превосходят Elasticsearch по производительности. А SQL, который был гораздо лучше разработан в Sphinx, чем в Elasticsearch даже сейчас, был привлекательным для многих.

В дополнение к поддержке существующих пользователей Sphinx, глобальной целью Manticore было реализовать вышеупомянутые и другие функции, которые сделали бы Manticore Search реальной альтернативой Elasticsearch в большинстве случаев использования.

Что мы уже сделали


Гораздо более активная разработка

Если вы посмотрите на статистику коммитов на github , вы можете увидеть, что как только произошел форк (середина 2017 года), темп разработки значительно увеличился:

img

За три с половиной года до марта 2021 года мы выпустили 39 новых версий. В 2020 году мы выпускали новую версию каждые два месяца.

Репликация

Многие пользователи ждали репликации в Sphinx в течение многих лет. Одной из первых крупных функций, которую мы реализовали в Manticore, была репликация. Как и все в Manticore, мы старались сделать ее как можно более удобной в использовании. Например, чтобы подключиться к кластеру, все, что вам нужно сделать, это выполнить команду, подобную этой:

JOIN CLUSTER posts at 'neighbour-server';

которая заставит индексы из кластера появиться на текущем узле.

Репликация в Manticore:

  • синхронная
  • основана на библиотеке Galera, которая также используется в MariaDB и Percona XtraDB.

Авто id

Без авто-id Sphinx / Manticore в основном считался просто расширением для другой базы данных (mysql, postgres и т.д.), поскольку должно было быть что-то, что генерирует ID. Мы реализовали авто-id на основе алгоритма UUID_SHORT. Уникальность гарантируется до 16 миллионов вставок в секунду на сервер, что должно быть достаточно во всех случаях.

mysql> create table idx(doc text);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into idx(doc) values('abc def');
Query OK, 1 row affected (0.00 sec)

mysql> select * from idx;
+---------------------+---------+
| id                  | doc     |
+---------------------+---------+
| 1514145039905718278 | abc def |
+---------------------+---------+
1 row in set (0.00 sec)

mysql> insert into idx(doc) values('def ghi');
Query OK, 1 row affected (0.00 sec)

mysql> select * from idx;
+---------------------+---------+
| id                  | doc     |
+---------------------+---------+
| 1514145039905718278 | abc def |
| 1514145039905718279 | def ghi |
+---------------------+---------+
2 rows in set (0.00 sec)

Хранение документов

В Sphinx 2.3.2 и ранее вы могли сохранять оригинальные тексты документов только в строковых атрибутах, которые (как и все атрибуты) должны храниться в памяти для оптимальной производительности. Многие пользователи делали это, нецелесообразно расходуя ОЗУ, что было дорого и могло вызывать неожиданные проблемы с производительностью при больших объемах. В Manticore мы создали новый тип данных text, который сочетает в себе полнотекстовую индексацию и хранение значения на диске с ленивым чтением (т.е. значение извлекается на самом последнем этапе запроса). Значения полей "хранится" не подлежат фильтрации и не могут быть отсортированы или сгруппированы. Они просто находятся в сжатом виде на диске, поэтому нет необходимости хранить их в mysql/hbase/postgres и других базах данных (если они действительно не нужны там). Это оказалось очень полезной и часто используемой функцией. С тех пор Manticore теперь требует ничего, кроме себя, для реализации поискового приложения.

Индексы в реальном времени

В Sphinx 2.3.2 и ранее многие пользователи испытывали трудности с использованием индексов в реальном времени, потому что это часто вызывало сбои и другие побочные эффекты. Мы исправили большинство известных ошибок и недостатков дизайна, и мы все еще работаем над некоторыми оптимизациями (в основном, связанными с автоматическим OPTIMIZE и изоляцией чтения/записи/слияния). Но уже можно с уверенностью сказать, что индексы в реальном времени могут использоваться в производстве, что на самом деле делает множество пользователей. Чтобы упомянуть несколько функций, которые мы добавили:

  • многопоточность: поиск в нескольких дисковых частях одного индекса в реальном времени выполняется параллельно
  • улучшения OPTIMIZE: по умолчанию части сливаются не в 1, а в количество ядер на сервере * 2 (это можно настроить через опцию cutoff ).

Мы работаем над автоматическим OPTIMIZE, чтобы пользователи не беспокоились о компактации вообще.

charset_table = cjk, non_cjk

Ранее, если вы хотели поддерживать какой-либо язык, кроме английского или русского, вам часто приходилось поддерживать большие массивы в charset_table. Это было неудобно. Мы упростили это, поместив все, что вам может понадобиться, в внутренние массивы charset_table, названные non_cjk (для большинства языков) и cjk (для китайского, корейского и японского). Массивы non_cjk являются стандартными для charset_table. Теперь вы можете искать на английском, русском и, скажем, турецком без проблем:

mysql> create table idx(doc text);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into idx(doc) values('abc абв öğrenim');
Query OK, 1 row affected (0.00 sec)

mysql> select * from idx where match('abc');
+---------------------+----------------------+
| id                  | doc                  |
+---------------------+----------------------+
| 1514145039905718280 | abc абв öğrenim      |
+---------------------+----------------------+
1 row in set (0.00 sec)

mysql> select * from idx where match('абв');
+---------------------+----------------------+
| id                  | doc                  |
+---------------------+----------------------+
| 1514145039905718280 | abc абв öğrenim      |
+---------------------+----------------------+
1 row in set (0.00 sec)

mysql> select * from idx where match('ogrenim');
+---------------------+----------------------+
| id                  | doc                  |
+---------------------+----------------------+
| 1514145039905718280 | abc абв öğrenim      |
+---------------------+----------------------+
1 row in set (0.00 sec)

Официальный образ Docker

Мы выпустили и поддерживаем официальный образ docker для Manticore Search. Теперь вы можете запустить Manticore за считанные секунды в любом месте, где есть docker.

  ~ docker run --name manticore --rm -d manticoresearch/manticore && docker exec -it manticore mysql && docker stop manticore

525aa92aa0bcef3e6f745ddeb11fc95040858d19cde4c9118b47f0f414324a79
mysql> create table idx(f text);
mysql> desc idx;
+-------+--------+----------------+
| Field | Type   | Properties     |
+-------+--------+----------------+
| id    | bigint |                |
| f     | text   | indexed stored |
+-------+--------+----------------+

Кроме того, тег manticore:dev всегда указывает на самую последнюю версию разработки Manticore Search.

Репозиторий пакетов

Все новые релизы и свежие версии разработки можно найти на https://repo.manticoresearch.com/

Оттуда вы также можете легко установить Manticore через YUM и APT . Мы также поддерживаем Homebrew и поддерживаем сборки для Windows.

NLP: Обработка естественного языка

В области NLP мы внесли следующие улучшения:

  • Сегментация китайского языка с использованием библиотеки ICU
  • стандартные стоп-слова для большинства языков из коробки:
mysql> create table idx(doc text) stopwords='en';
Query OK, 0 rows affected (0.05 sec)

mysql> call keywords('to be or not to be that is the question', 'idx');
+------+-----------+------------+
| qpos | tokenized | normalized |
+------+-----------+------------+
| 10   | question  | question   |
+------+-----------+------------+
1 row in set (0.01 sec)
mysql> insert into idx(doc) values('Polly wants a cracker');
Query OK, 1 row affected (0.09 sec)

mysql> select highlight() from idx where match('polly cracker');
+-------------------------------------+
| highlight()                         |
+-------------------------------------+
| <b>Polly</b> wants a <b>cracker</b> |
+-------------------------------------+
1 row in set (0.10 sec)

Новый режим многозадачности

Для многозадачности Manticore теперь использует корутины. В дополнение к тому, что код стал намного проще и надежнее, больше не требуется использовать разные значения dist_threads для разных индексов, чтобы оптимально параллелить поиски по ним. Теперь есть глобальная настройка threads, которая по умолчанию равна количеству ядер на сервере. В большинстве случаев вам не нужно вообще ее трогать для оптимальной производительности.

Поддержка OR в WHERE

В Sphinx 2/3 вы не можете легко фильтровать по атрибутам, используя оператор OR, что является большим ограничением. Мы исправили это в Manticore:

mysql> select i, s from t where i = 1 or s = 'abc';
+------+------+
| i    | s    |
+------+------+
|    1 | abc  |
|    1 | def  |
|    2 | abc  |
+------+------+
3 rows in set (0.00 sec)

Sphinx 3:
mysql> select * from t where i = 1 or s = 'abc';
ERROR 1064 (42000): sphinxql: syntax error, unexpected OR, expecting $end near 'or s = 'abc''

Поддержка JSON протокола через HTTP

SQL — это здорово. Мы любим SQL. И в Sphinx / Manticore все, что касается синтаксиса запросов, можно сделать через SQL. Но есть ситуации, когда лучшее решение — использовать JSON интерфейс, как в Elasticsearch. SQL отлично подходит для проектирования запросов, в то время как JSON хорош, когда вам нужно интегрировать сложный запрос в ваше приложение.

Кроме того, HTTP позволяет делать много интересных вещей: использовать внешние HTTP балансировщики нагрузки и проксирование, что позволяет легко реализовать аутентификацию, RBAC и т. д.

Новые клиенты для большего количества языков

Еще проще, чем использовать JSON через HTTP, — это использовать клиент для конкретного языка программирования, на котором написано ваше приложение. Мы реализовали новые клиенты для php , python , java , javascript , elixir , go . Большинство из них основаны на новом JSON интерфейсе, и их код генерируется автоматически, что позволяет нам быстрее добавлять новые функции в клиенты.

Поддержка HTTPS

Безопасность имеет значение. Мы сделали поддержку HTTPS доступной из коробки. Все еще лучше не выставлять экземпляр Manticore Search в интернет, так как нет встроенной аутентификации, но теперь безопаснее передавать запросы и результаты от клиента к Manticore Search по локальной сети. SSL для mysql-интерфейса также поддерживается.

Поддержка FEDERATED

В дополнение к SphinxSE (встроенный mysql движок, который позволяет более тесно интегрировать Sphinx/Manticore с mysql) вы теперь можете использовать FEDERATED движок MySQL, который доступен в MySQL и MariaDB.

Поддержка ProxySQL

ProxySQL также поддерживается и вы можете использовать его для выполнения довольно интересных вещей, которые расширяют возможности Manticore Search.

RT режим

Одним из основных изменений, которые мы внесли, был императивный (т.е. через CREATE/ALTER/DROP table) способ работы с Manticore. Как вы можете видеть из приведенных выше примеров SQL, вам больше не нужно определять индекс в конфигурации. Как и в других базах данных, теперь вы можете создавать, изменять и удалять индексы в Manticore на лету без необходимости редактировать конфигурацию, перезапускать экземпляр, удалять файлы индекса в реальном времени и все эти хлопоты. Схема данных теперь полностью отделена от настроек сервера. И это стандартный режим. Мы называем его RT режим.

Но декларативный режим (мы называем его Plain режим) также по-прежнему поддерживается. Мы не считаем его рудиментом и не планируем от него избавляться. Так же, как вы можете общаться с Kubernetes обоими способами, либо через yaml файлы, либо через конкретные команды, вы можете общаться с Manticore аналогично:

  • вы можете описать все в конфигурации и воспользоваться возможностью легкой портируемости конфигурации и более быстрого развертывания индексов,
  • или вы можете создавать индексы на лету, что позволяет легче интегрировать их в ваше приложение

Смешивать использование режимов невозможно и не планируется.

Индекс перколяции

Обычный способ выполнения поисковых запросов заключается в хранении документов, которые мы хотим искать, и выполнении запросов к ним. Однако есть случаи, когда мы хотим применить запрос к входящему новому документу, чтобы сигнализировать о совпадении. Есть несколько сценариев, когда это необходимо. Например, система мониторинга не просто собирает данные, но также желательно уведомлять пользователя о различных событиях. Это может быть достижение некоторого порога для метрики или определенного значения, которое появляется в отслеживаемых данных. Другой аналогичный случай — агрегирование новостей. Вы можете уведомить пользователя о любых свежих новостях, но пользователь может захотеть получать уведомления только о определенных категориях или темах. Двигаясь дальше, их могут интересовать только определенные "ключевые слова". Все это теперь возможно в Manticore, если вы используете percolate index.

mysql> create table t(f text, j json) type='percolate';
mysql> insert into t(query,filters) values('abc', 'j.a=1');
mysql> call pq('t', '[{"f": "abc def", "j": {"a": 1}}, {"f": "abc ghi"}, {"j": {"a": 1}}]', 1 as query);
+---------------------+-------+------+---------+
| id                  | query | tags | filters |
+---------------------+-------+------+---------+
| 8215503050178035714 | abc   |      | j.a=1   |
+---------------------+-------+------+---------+

Работает быстрее, чем в Elasticsearch .

Новая удобная документация - https://manual.manticoresearch.com

Для ключевых функций Manticore Search есть примеры для большинства поддерживаемых клиентов. Поиск в руководстве, конечно, использует Manticore Search в качестве бэкенда. Что еще:

  • Умное выделение результатов поиска в результатах поиска
  • Примеры HTTP можно скопировать одним щелчком мыши прямо как команду curl с параметрами
  • Кроме того, у нас есть специально зарегистрированный короткий домен mnt.cr, чтобы вы могли очень быстро найти информацию о чем-то, что вам нужно прямо сейчас, нажав CTRL-T/CMD-T в вашем браузере и набрав, например, mnt.cr/proximity , mnt.cr/quorum , mnt.cr/percolate .

Интерактивные курсы - https://play.manticoresearch.com

Чтобы упростить начало работы с Manticore Search, мы создали платформу для интерактивных курсов https://play.manticoresearch.com и, конечно, сами курсы, которые вы можете пройти прямо из вашего браузера, не устанавливая ничего. За несколько секунд вы можете увидеть, как работает репликация Manticore Search или как выделять результаты поиска

Github как трекер ошибок

Мы используем Github в качестве публичного трекера ошибок/задач.

Sphinx 3


Sphinx 3.0.1 был выпущен в декабре 2017 года. До октября 2018 года было выпущено еще три версии и одна в июле 2020 года (3.3.1, последняя версия на март 2021 года). Появилось много интересных функций, включая вторичные индексы и некоторые возможности машинного обучения. Так в чем же проблема? Зачем людям вообще нужен Manticore? Одна из причин заключается в том, что, к сожалению, ни первый релиз Sphinx 3, ни последний в настоящее время не являются открытым исходным кодом:

  • оба в том смысле, что код Sphinx 3 недоступен
  • и в широком смысле открытого исходного кода . На странице загрузок говорится , что Sphinx теперь доступен под лицензией "отложенный FOSS". Что именно это за лицензия и где ее можно найти, не раскрывается. Неясно:
  • является ли это все еще GPLv2 (т.е. "отложенный FOSS" означает отложенный GPLv2), поскольку код, вероятно, основан на Sphinx 2, который является GPLv2 (как и Manticore). Но тогда где исходный код?
  • или это не GPLv2, потому что лицензия не прикреплена к бинарным файлам, и неизвестно, основан ли код вообще на Sphinx 2 или нет? Применяются ли ограничения GPLv2? Можно ли распространять бинарные файлы Sphinx 3 по своему усмотрению, поскольку текста лицензии нет?
  • С июля 2020 года не было выпущено ни одной версии. Есть много ошибок , включая серьезные сбои. Когда они будут исправлены?

Существует много вопросов и нет ответов. Все это делает использование Sphinx 3 очень рискованным для компаний и отдельных лиц, которые заботятся о правовой стороне дела и стабильности проекта. Не многие компании имеют возможность инвестировать время своих сотрудников в проект, который выглядит замороженным и имеет такую неясную лицензию.

В целом Sphinx 3 теперь можно считать проприетарным решением для ограниченного круга пользователей с очень специфическими целями. Жаль, что мир открытого исходного кода потерял Sphinx. Мы можем только надеяться, что что-то изменится в будущем.

Есть ли бенчмарки?


Да! Давайте протестируем набор данных , состоящий из более чем 1 миллиона комментариев с HackerNews и числовых атрибутов.

Больше о тесте:

  • простой индекс, построенный из набора данных. Размер файлов индекса составляет около 1 гигабайта
  • набор различных запросов (132 запроса) от полнотекстового поиска до фильтрации и группировки
  • докеры, работающие на сервере с bare-metal с различными ограничениями по памяти
  • мы используем SQL через клиент mysqli из PHP-скрипта для выполнения запросов
  • перед каждым новым запросом мы очищаем все кэши, включая кэш ОС, и перезапускаем докер, затем мы проводим 5 попыток, наименьшее время отклика идет в статистику.

Результаты:

Лимит 100 мегабайт:

img

Лимит 500 мегабайт:

img

Лимит 1000 мегабайт:

img

Будущее Manticore Search


Итак, у нас уже есть активно разрабатываемый продукт под четкой лицензией открытого исходного кода GPLv2 с репликацией, авто-ID, правильно работающими индексами в реальном времени, JSON-интерфейсом, хорошей документацией, интерактивными курсами и многим другим. Что дальше? Наша дорожная карта:

Новый движок Manticore

С начала 2020 года мы работаем над библиотекой колонного хранения и обработки с индексированием по умолчанию (в отличие от, скажем, Clickhouse). Для пользователей Manticore и Sphinx это решит следующие проблемы:

  • необходимость в большом объеме ОЗУ для быстрого поиска в большом количестве документов и атрибутов
  • субоптимальная производительность группировки
  • субоптимальная производительность фильтрации, когда часть атрибутов не помещается в ОЗУ

Мы уже имеем бета-версию и вот некоторые первые результаты сравнения библиотеки Manticore Columnar + Manticore Search с Elasticsearch на том же наборе данных, что и выше (исключая полнотекстовые запросы, т.е. в основном группировочные запросы):

img

Еще предстоит проделать много работы. Библиотека доступна под более свободной лицензией Apache 2.0 и может использоваться как в Manticore Search, так и в других проектах (в Sphinx тоже, если им нравится).

Авто OPTIMIZE

Мы понимаем, как неудобно вручную вызывать OPTIMIZE для компактации индексов в реальном времени. Мы работаем над решением этой проблемы и надеемся, что это будет включено в следующий релиз. Следите за нами в twitter , чтобы не пропустить это.

Интеграция с Kibana

Поскольку пользователи теперь могут проводить больше аналитики с новым движком Manticore, было бы неплохо иметь возможность легко визуализировать это. Grafana хороша, но может быть немного сложной для использования с полнотекстовым поиском. Kibana тоже хороша, многие люди знают и используют ее. У нас есть альфа-версия интеграции между Manticore Search и Kibana. Она не доступна публично, но как только мы закончим исправление ошибок и сможем считать ее бета-версией, она будет открыта.

Интеграция с Logstash

Manticore Search уже имеет JSON-протокол. Мы собираемся улучшить методы PUT и POST, чтобы сделать их совместимыми с Elasticsearch для запросов INSERT/REPLACE. Кроме того, мы планируем сделать возможным создание индекса на лету на основе первых вставленных документов. Все это позволит вам записывать данные в Manticore Search вместо Elasticsearch из Logstash, Fluentd, Beats и подобных инструментов.

Автоматическое шардирование

Это еще один проект в процессе. Мы уже понимаем, с какими трудностями нам придется столкнуться и более или менее как их решить. Мы планируем это на второй квартал.

Альтернатива Logstash

Logstash требует от пользователя потратить много времени на начало работы с новым пользовательским типом логов. И если вы добавите любую новую строку, правила парсинга придется обновлять. В последние несколько месяцев мы разрабатываем систему, которая может почти полностью решить эту проблему. Она позволит вам парсить ваши логи практически без помощи и с удобным интерфейсом для именования ваших полей и окончательной донастройки.

Если вам нравится то, что мы делаем, оставайтесь с нами:

Установить Manticore Search

Установить Manticore Search