В мае 2017 года мы сделали форк Sphinxsearch 2.3.2, который назвали Manticore Search . Ниже вы найдёте краткий отчёт о Manticore Search как форке Sphinx и наших достижениях с тех пор.
Почему мы форкнули Sphinx?
Прежде всего, почему мы сделали форк? В конце 2016 года работа над Sphinxsearch была приостановлена. Пользователи, использующие Sphinx, и некоторые заказчики, поддерживавшие разработку проекта, волновались из‑за того, что:
- баги не исправлялись длительное время
- новые функции, обещанные давно, не появлялись
- связь с командой Sphinx была нарушена
Через несколько месяцев ситуация не изменилась, и в середине июня 2017 года группа инициативных и опытных пользователей Sphinx и поддерживающих клиентов собралась вместе и решила попытаться сохранить продукт в виде форка под названием Manticore Search. Нам удалось собрать обратно большую часть прежней команды Sphinx, уже работающей в разных компаниях, привлечь инвестиции и за короткое время восстановить полноценную работу над проектом.
Каковы были наши цели?
Форк ставил перед собой три задачи:
- Общая поддержка кода: исправление багов, небольшие и крупные новые функции
- Поддержка пользователей Sphinx и Manticore
- Более интенсивная разработка продукта, чем была ранее. К сожалению, к тому времени Elasticsearch уже обогнал Sphinx во многих отношениях.
Такие вещи, как:
- отсутствие репликации
- отсутствие авто‑идентификатора
- отсутствие JSON‑интерфейса
- отсутствие возможности создавать/удалять индекс «на лету»
- отсутствие хранения документов
- незрелые индексы реального времени
- фокус на полнотекстовый поиск, а не на поиск в целом
делали Sphinx очень специализированным решением, требующим ручной настройки во многих случаях. К тому времени многие пользователи уже перешли на Elasticsearch. Это было печально, потому что фундаментальные структуры данных и алгоритмы в Sphinx потенциально и фактически во многих случаях превосходили Elasticsearch по производительности. А SQL, который был гораздо лучше развит в Sphinx, чем в Elasticsearch даже сейчас, привлекал многих.
Помимо поддержки существующих пользователей Sphinx, глобальная цель Manticore заключалась в реализации вышеупомянутых и других функций, которые сделают Manticore Search реальной альтернативой Elasticsearch в большинстве сценариев использования.
Что мы уже сделали
Гораздо более активная разработка
Если посмотреть на статистику коммитов на GitHub , можно увидеть, что сразу после форка (середина 2017) темпы разработки резко возросли:

За три с половиной года до марта 2021 года мы выпустили 39 новых версий. В 2020 году мы выпускали новую версию каждые два месяца.
Репликация
Многие пользователи ждали репликацию в Sphinx годами. Одной из первых крупных функций, которую мы реализовали в Manticore, стала репликация. Как и всё в Manticore, мы постарались сделать её максимально простой в использовании. Например, чтобы подключиться к кластеру, достаточно выполнить команду вроде этой:
JOIN CLUSTER posts at 'neighbour-server';
что заставит индексы из кластера появиться на текущем узле.
Репликация в Manticore:
- синхронная
- основана на библиотеке Galera, которая также используется в MariaDB и Percona XtraDB.
Авто‑идентификатор
Без auto-id Sphinx / Manticore в основном рассматривался лишь как расширение к другой базе данных (mysql, postgres и т.д.), поскольку требовалось что‑то, генерирующее 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 и более ранних версиях можно было сохранять оригинальные тексты документов только в строковых атрибутах, которые (как и все атрибуты) хранились в памяти для оптимальной производительности. Многие пользователи делали так, тратя RAM без необходимости, что было дорого и могло вызывать неожиданные проблемы с производительностью при больших объёмах. В Manticore мы
создали
новый тип данных text, который сочетает полнотекстовое индексирование и хранение значения на диске с «ленивым» чтением (т.е. значение извлекается на самом последнем этапе запроса). Значения поля «stored» не фильтруются и не могут быть отсортированы или сгруппированы. Они просто находятся в сжатом виде на диске, поэтому нет необходимости хранить их в mysql/hbase/postgres и других базах данных (если только они действительно не нужны там). Это оказалось очень полезной и часто используемой функцией. С тех пор Manticore теперь требует ничего, кроме самого себя, для реализации поискового приложения.
Индексы реального времени
В Sphinx 2.3.2 и более ранних версиях многие пользователи сталкивались с проблемами при использовании индексов реального времени, поскольку они часто приводили к сбоям и другим побочным эффектам. Мы исправили большинство известных багов и проектных недостатков и продолжаем работать над некоторыми оптимизациями (в основном, связанными с автоматическим OPTIMIZE и изоляцией чтения/записи/слияния). Но уже можно с уверенностью сказать, что индексы реального времени можно использовать в продакшене, что и делают многие пользователи. Несколько добавленных функций:
- многопоточность: поиск в нескольких дисковых чанках одного индекса реального времени выполняется параллельно
- улучшения OPTIMIZE: по умолчанию чанки объединяются не в один, а в количество ядер сервера * 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)
Official Docker image
Мы выпустили и поддерживаем официальное docker‑image для 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.
Packages repository
Все новые релизы и свежие версии разработки можно найти по адресу https://repo.manticoresearch.com/
Оттуда вы также можете легко установить Manticore через YUM и APT . Мы также поддерживаем Homebrew и поддерживаем сборки для Windows.
NLP: Natural Language Processing
В области 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)
- Поддержка Snowball 2.0 для большего количества языков
- Упрощённое подсвечивание синтаксиса:
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)
New multitasking mode
Для многозадачности Manticore теперь использует корутины. Помимо того, что код стал гораздо проще и надёжнее, теперь не требуется использовать разные значения dist_threads для разных индексов, чтобы оптимально параллелить поиск. Теперь существует глобальная настройка threads, которая по умолчанию равна количеству ядер на сервере. В большинстве случаев вам вовсе не нужно её менять для достижения оптимальной производительности.
OR support in 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 protocol support via HTTP
SQL крут. Мы любим SQL. И в Sphinx / Manticore всё, что касается синтаксиса запросов, можно делать через SQL. Но бывают ситуации, когда лучше использовать JSON‑интерфейс, как
например, в Elasticsearch. SQL отлично подходит для проектирования запросов, тогда как JSON превосходит, когда нужно интегрировать сложный запрос в приложение.
Кроме того, HTTP позволяет делать множество интересных вещей: использовать внешние HTTP‑балансировщики нагрузки и проксирование, что упрощает реализацию аутентификации, RBAC и т.д.
New clients for more languages
Ещё проще, чем использовать JSON через HTTP, — использовать клиент для конкретного языка программирования, на котором написано ваше приложение. Мы реализовали новые клиенты для php , python , java , javascript , elixir , go . Большинство из них основаны на новом JSON‑интерфейсе, а их код генерируется автоматически, что позволяет нам гораздо быстрее добавлять новые возможности в клиенты.
HTTPS support
Безопасность имеет значение. Мы сделали поддержку HTTPS доступной сразу из коробки. Всё равно лучше не выставлять экземпляр Manticore Search в интернет, так как встроенной аутентификации нет, но теперь безопаснее передавать запросы и результаты от клиента к Manticore Search по локальной сети. SSL для mysql‑интерфейса также поддерживается.
FEDERATED support
В дополнение к SphinxSE (встроенному mysql‑движку, позволяющему более тесно интегрировать Sphinx/Manticore с mysql) теперь можно использовать движок FEDERATED от MySQL, который доступен в MySQL и MariaDB.
ProxySQL support
ProxySQL также поддерживается и вы можете использовать его для создания довольно интересных возможностей, расширяющих функциональность Manticore Search.
RT mode
Одним из главных изменений, которые мы внесли, стал императивный (т.е. через CREATE/ALTER/DROP table) способ работы с Manticore. Как видно из приведённых выше примеров SQL, теперь не нужно определять индекс в конфигурации. Как и в других базах данных, теперь вы можете создавать, изменять и удалять индексы в Manticore «на лету», без необходимости редактировать конфигурацию, перезапускать экземпляр, удалять файлы реального времени и прочих хлопот. Схема данных теперь полностью отделена от настроек сервера. И это режим по умолчанию. Мы называем его RT mode.
- Но декларативный режим (мы называем его
Plain mode) также по‑прежнему поддерживается. Мы не считаем его устаревшим и не планируем от него отказываться. Точно так же, как вы можете взаимодействовать с 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 недоступен
- и в более широком смысле «open source» — см. broader sense of open source . На странице загрузок говорится , что Sphinx теперь доступен по лицензии «delayed FOSS». Что именно представляет собой эта лицензия и где её можно найти, не раскрывается. Неясно:
- является ли она всё ещё GPLv2 (т.е. «delayed 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 мегабайт лимит:

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

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

Будущее Manticore Search
Итак, у нас уже есть активно разрабатываемый продукт под чёткой открытой лицензией GPLv2 с репликацией, авто‑идентификатором, корректно работающими реальными‑временными индексами, JSON‑интерфейсом, хорошей документацией, интерактивными курсами и многим другим. Что дальше? Наш дорожный план таков:
Новый движок Manticore
С начала 2020 года мы работаем над колонковой системой хранения и обработки с индексированием по умолчанию (в отличие, скажем, от Clickhouse). Для пользователей Manticore и Sphinx это решит следующие проблемы:
- необходимость большого объёма ОЗУ для быстрого поиска в большой коллекции документов и атрибутов
- субоптимальная производительность группировки
- субоптимальная производительность фильтрации, когда часть атрибутов не помещается в ОЗУ
У нас уже есть beta версия готова и вот некоторые первые результаты сравнения Manticore Columnar Library + Manticore Search с Elasticsearch на том же наборе данных, что и выше (за исключением полнотекстовых запросов, т.е. в основном запросов группировки):

Все еще предстоит выполнить много работы. Библиотека доступна под более либеральной открытой лицензией Apache 2.0 и может использоваться в Manticore Search, а также в других проектах (в Sphinx тоже, если захотят).
Авто ОПТИМИЗАЦИЯ
Мы понимаем, насколько неудобно вызывать 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 требует от пользователя тратить много времени на начало ingest‑а из нового custom типа логов. И если вы добавляете любую новую строку, правила парсинга придётся обновлять. За последние несколько месяцев мы разрабатывали систему, которая может решить эту проблему почти полностью. Она позволит вам парсить ваши логи практически без помощи и с удобным UI для именования полей и финальной тонкой настройки.
Если вам нравится то, что мы делаем, оставайтесь с нами:
