5 лет назад мы сделали форк Manticore из open source версии некогда популярного  open source поискового движка Sphinx 2.3.2. У нас было два пакетика травы, семьдесят пять ампул мескалина, три C++ разработчика, один саппорт-инженер, опытный пользователь, менеджер, мать пятерых детей, помогающая нам на полставки и гора багов, крэшей и технических долгов. Взяв в руки напильники и прочий шанцевый инструмент мы начали допиливать форк до индустриальных стандартов (читай "Эластика"). Не то чтобы Sphinx было невозможно использовать, но многих вещей не хватало, а имеющиеся не всегда работали стабильно и корректно, а если уж начал, то к делу надо подходить серьёзно. И вот, по прошествии 5 лет и сотен новых пользователей мы готовы сказать, что Manticore можно использовать как альтернативу Elasticsearch и для полнотекстового поиска и для аналитики данных. В этой статье хочется: вспомнить, как всё начиналось и что было до SOLR и Elasticsearch; объективно обрисовать текущую ситуацию c Manticore; попытаться понять куда нам двигаться дальше. Немного истории ✳️ Скорость поиска ✳️ Скорость поиска ✳️ Скорость записи ✳️ На чём написано ✳️ Open source ✳️ Json vs SQL ✳️ Скорость запуска и легковесность процесса ✳️ Near-real-time vs real-time ✳️ Полнотекст ✳️ Schemaless ✳️ Интеграции с приложениями ✳️ Репликация ✳️ Шардинг и распределённые таблицы ✳️ Простота изучения и использования ✳️ Что дальше? ✳️ Выводы 2001 Открылся первый Apple store, зарелизился Windows XP, iTunes и Max OS X. Гениальный Андрей Аксёнов начал работать над Sphinx Search, за что ему большое спасибо! Ещё не было ни SOLR, ни тем более Elasticsearch, но уже был Lucene, на котором они оба и были в дальнейшем построены. 2010 Появился Retina-дисплэй, systemd, айпад и Elasticsearch. К этому времени Sphinx уже был популярным полнотекстовым движком, но концепция Сфинкса “данные лежат где-то, а мы просто делаем полнотекстовый индекс, который нужно регулярно перестраивать”,  оказалась уже не такой интересной, как эластиковская “пишите в меня по HTTP что угодно в real-time, я сам разберусь что к чему и разложу по нодам”. У SOLR на тот момент было не всё хорошо с распределённостью, да и JSON набирал популярность, а XML улетал, но обещал вернуться. В итоге Эластик начал быстро набирать популярность. 2017: прошло ещё 7 лет. Эластик прочно закрепился как стандартный инструмент для полнотекстового поиска и аналитики по логам и данным. Sphinx прекратил своё развитие в виде open source проекта, да и разработка в принципе существенно замедлилась, а на какое-то время была полностью приостановлена Многим пользователям Sphinx, которые умели его готовить было больно переходить на Elasticsearch. Кроме того, к тому моменту повылазили концептуальные недостатки Эластика: чрезмерное потребление памяти, сложности в поддержании больших кластеров, некоторые проблемы с производительностью. В итоге, фрустрирующие пользователи и некоторые бывшие разработчики Сфинкса объединились и сделали форк - Manticore Search. Наши первоочередные цели были следующие:  Продолжить развитие проекта в виде open source Взглянуть на всё со стороны рядового юзера и добавить функциональность так необходимую ему в современных условиях И всё это вылить в то, чтоб усилить сильные стороны и подтянуть слабые. 2022: прошло ещё пять лет. Мы строили, строили и наконец построили. 🙁 Sphinx 2: Основной способ использования - индексация данных из внешней БД: Sphinx возвращает id, затем по id нужно идти в БД и искать там исходных документ. Схема данных соответственно описывается через конфиг. ✅ Manticore: Основной способ использования - ровно такой же, как в Mysql / Postgres и Elasticsearch: таблица создаётся запросом, данные пишут одиночными или bulk insert/replace/delete запросами, в фоне автоматически оптимизируются, за исходными документами никуда ходить не нужно. Добавлена поддержка auto id. 🙁 Sphinx 2: Нет репликации ✅ Manticore: Есть репликация, основанная на Galera, которую также использую в Mariadb и Percona Server 🙁 Sphinx 2: Запросы можно выполнять через SQL (протокол - mysql) или бинарный протокол, есть клиенты для некоторых языков программирования. ✅ Manticore: Добавился JSON похожий на эластиковский. На основе нового протокола были сделаны новые клиенты для php, python, java, javascript, elixir. Клиенты генерируются автоматически, что позволяет быстрее делать доступной новую функциональность. 🙁 Sphinx 2: Сложно настраивать токенизацию текстов для большинства языков ✅ Manticore: Упростили: сделали алиасы cjk и non_cjk. Сделали токенизацию китайского на основе ICU. Добавили много новых стеммеров, в том числе для украинского. 🙁 Sphinx 2: Нет официального docker’а и никакой поддержки в экосистеме Kubernetes ✅ Manticore: Сделали и поддерживаем официальный docker. Сделали и поддерживаем Helm chart для Kubernetes 🙁 Sphinx 2: Нет APT/YUM/Homebrew репозиториев ✅ Manticore: Добавили APT/YUM/Homebrew репозитории. Поддерживаются development ветки репозиториев, есть CI: пакеты собираются для всех новых коммитов. 🙁 Sphinx 2: Некоторым начинающим пользователям сложно понять что к чему. ✅ Manticore: Сделали платформу с интерактивными курсами - https://play.manticoresearch.com/ 🙁 Sphinx 2: Мало примеров в документации ✅ Manticore: переписали документацию, сделали для неё собственный движок - https://manual.manticoresearch.com/ 🙁 Sphinx 2: Баги, часто приводящие к крэшам ✅ Manticore: Крэши теперь - большая редкость. Сотни старых багов были пофикшены. 🙁 Sphinx 2: Распараллеливание поискового запроса возможно только в режиме один физический индекс (чанк) - один тред ✅ Manticore: Передалали всё на корутины. Сделали возможность распараллеливать любой поисковый запрос так, чтоб полностью загружать проц и уменьшать время отклика до минимума 🙁 Sphinx 2: Нельзя использовать без полнотекста ✅ Manticore: Можно использовать совсем без полнотекста, как любую другую базу данных 🙁 Sphinx 2: Неполнотекстовые данные хранятся построчно, для эффективной работы они должны быть в памяти. ✅ Manticore: Реализовали Manticore Columnar Library - внешнюю полностью независимую библиотеку, которая позволяет хранить данные поколоночно в блоках с поддержкой разных кодеков для сжатия для разных типов данных. Памяти почти не требует. Теперь можно обрабатывать намного большие объёмы. 🙁 Sphinx 2: Нет вторичных индексов ✅ Manticore: Вторая важная функциональность Manticore Columnar LIbrary - поддержка вторичных индексов на основе современного и инновационного алгоритма PGM. 🙁 Sphinx 2: Нет типа таблиц percolate для реверсивного поиска (когда в таблице лежат запросы, а на вход подаются документы, чтоб понять какие запросы их бы нашли) ✅ Manticore: Добавили таблицы типа percolate. Это, наверное, только треть нововведений - те, которые можно увидеть невооружённым взглядом. Кроме этого, были долгие месяцы рефакторинга различных частей системы, в результате чего код стал намного проще, надёжнее и производительнее. Мы надеемся, что это привлечёт в проект новых разработчиков. С Эластиком всё хорошо: он не очень сложен в использовании до определённого объёма данных, есть репликация, отказоустойчивость, богатый функционал. Но есть нюансы. Давайте поглядим на эти нюансы и на то, что из себя представляет Manticore по сравнению с Elasticsearch сейчас (июль 2022). Читатель из будущего, мы уже ещё что-то прикрутили, посмотри Changelog. Производительность, а именно низкое время отклика важно во многих случаях, особенно в области аналитики по логам и данным, когда данных много, а поисковых запросов не очень. Не хочется же ждать ответа на запрос 30 секунд вместо двух? Не хочется. Так вот, к нюансам: Elasticsearch считается стандартом для log management’а, но, например, не умеет эффективно распараллеливать запрос к одному шарду индекса. А по дефолту у Elasticsearch всего 1 шард, а ядер в современных серверах намного больше. Слишком много шардов, с запасом - тоже плохо. Всё это не делает жизнь девопса, которому не всё равно на время отклика проще: нужно думать о том, на каком железе будет работать Эластик и делать соответствующие изменения. Manticore же умеет распараллеливать поисковый запрос на все ядра безусловно и по умолчанию. Правильнее будет сказать, что Мантикора сама решает когда распараллеливать, а когда нет, но в большинстве случаев она это делает, что позволяет эффективно загрузить ядра процессора (зачастую простаивающие в случаях аналитики по логам и данным) и существенно уменьшить время отклика. Но даже если в Эластике сделать столько шардов, сколько есть ядер на сервере, то Мантикора оказывается существенно быстрее, а именно: вот тест на 1.7 миллиарда документов, из него видно, что в общем и целом Manticore в 4 раза быстрее Эластика. Интересны детали или хотите сами воспроизвести на своём железе? Вот статья https://db-benchmarks.com/test-taxi/ (все примеры ниже также подкреплены скриптами и ссылками, пустословия в этой статье вы не найдёте). Вот полярная ситуация: данных очень мало - всего 1.1 миллиона комментариев с Hacker News. И тут Manticore в разы быстрее Эластика. Детали здесь. И ещё один тест показательный для Эластика как стандартного инструмента для анализа логов - 10 миллионов логов Nginx'а и различные вполне реалистичные аналитические запросы - Мантикора в 22 раза быстрее Эластика. Все детали по ссылке https://db-benchmarks.com/test-logs10m/ . В общем, в низкий latency мы умеем, можем и у нас это неплохо получается на данных разного масштаба и разной структуры. Со скоростью записи в Эластик тоже есть нюансы. Например, датасет для теста на 1.7 миллиарда документов, рассмотренного выше был загружен: В Elasticsearch - за 28 часов 33 минуты; В Manticore - за 1 час 8 минут. Это на 32-ядерном сервере с SSD. Объёмы данных после индексации получились плюс-минус одинаковые. Про то, как именно происходила загрузка можно узнать здесь. Вкратце: Источник - csv. В Эластике загрузка через logstash c PIPELINE_BATCH_SIZE=10000 и PIPELINE_WORKERS=32 в 32 шарда. В Мантикоре - параллельная индексация в 32 шарда. Логи загрузочного скрипта получились такие:   Выходит, что Manticore в 25 раз быстрее в плане скорости заливки. Может быть я конечно не умею ни в Logstash, ни в Elasticsearch, но у известного в узких кругах Марка Литвинчика импорт этого же датасета (но чуть меньшего объёма) занял ещё больше - 4 дня 16 часов. Может Logstash всё портит? Давайте попробуем без него. Схема индекса такая: Запустим Мантикору и Эластик в докере вот так: и запишем в Эластик и Мантикору 50 миллионов подобных документов: Писать будем php-скриптами с batch size 10,000 документов и в 32 потока (на сервере 16 физических ядер с гипертредингом, т.е. 32 виртуальных) через JSON интерфейс. Эластик быстрее на 21%, но опять же есть интересный нюанс: Elasticsearch по умолчанию буферизирует добавленные документы на одну секунду, то есть для поиска очередной батч будет доступен не сразу. Это во многих случаях ок, но для чистоты эксперимента если в Эластике сделать /bulk?refresh=1 , то перформанс получается уже другой: В этом случае уже Мантикора на 43% быстрее. Если же гнаться за максимальной производительностью, то можно: Использовать шардинг и в Эластике, и в Мантикоре. В Эластике по максимуму использовать буферизацию и обработать буфер уже после заливки. Заливать в Мантикору через mysql протокол, а не JSON. Отключить в Мантикоре binlog (в Эластике так нельзя). Тогда получится: Manticore: Elasticsearch: Но после этого видимых документов в индексе не будет и нужно ещё 13 секунд, чтобы сделать их таковыми: В данном случае Мантикора в 2 раза быстрее Эластика. И при этом данные доступны для поиска сразу же после заливки очередного батча, а не через 2 минуты. Использованные для этого теста скрипты можно найти здесь. Эластик и сам написан на Джаве, и библиотека Lucene, который она использует и от которой зависит - тоже Java. Мантикора -  С++. Что это даёт:  Код писать сложнее. Но ближе к железу, поэтому можно сделать более оптимизированный код. Не надо думать о JVM heap size. Нет риска запуска JVM garbage collector’а в неподходящий момент, что может сильно влиять на производительность. При старте не нужно запускать тяжелую JVM и тратить на это несколько секунд. Эластик - уже не чистый open source. В 2021 году лицензия была изменена с Apache 2 на Elastic License. Мантикора - чистый open source на GPLv2 у демона и Apache2 у columnar library . И Эластик и Manticore умеют и SQL и JSON, но разница в том, что: В Эластике по умолчанию подразумевается JSON, а в Manticore SQL. На SQL многие вещи делать намного проще на этапе proof of concept. Вот например 2 запроса, которые делают одно и то же. Решайте сами что интереснее: потратить минуту на скобочки или: SQL в эластике очень ограниченный, например нет: SELECT id; INSERT/UPDATE/DELETE; Cлужебных команд (создание кластера, отображение статуса и т.п.). В Manticore наоборот:  SQL умеет всё; А JSON покрывает базовую функциональность: поисковые запросы и запросы на вставку и обновление данных. В некоторых случаях нужно уметь быстро запустить сервис. Например, в IOT (Internet of things) или в каких-то ETL сценариях. Elasticsearch стартует долго; Мантикоре нужна пара секунд, чтоб запуститься с таблицей на 1.1 миллиона документов. Как говорилось выше, по умолчанию когда вы пишете в Elasticsearch, данные становятся доступны для поиска только через секунду. Это можно настроить, но тогда скорость заливки будет существенно ниже, как видно выше. Manticore всегда работает в real-time режиме. Про это можно написать отдельную статью. Если коротко: и Мантикора и Эластик умеют много что в плане полнотекстового поиска, много общего, но есть много отличий. По объективным тестам (что важно при оценке релевантности) на практически дефолтных настройках Manticore может дать более высокую релевантность, чем Elasticsearch. Вот соответствующий PR в BEIR (Information retrieval benchmark). По этому пункту есть существенные отличия. Эластик славится тем, что в него можно писать что угодно. В Мантикоре нужно заранее создать схему. Возможность работы с Manticore в schemaless режиме у нас в планах. Мы считаем, что это важно, так как это делает жизнь проще, особенно в области log management’а. Клиенты для различных языков программирования есть и у Эластика и у Мантикоры. MySQL:  Важным отличием Мантикоры является возможность использования mysql-клиентов для полноценной работы с сервером. Даже если для какого-то ЯП нет официального клиента, то там точно есть mysql-клиент, который можно использовать.  Использование command line mysql клиента для администрирования удобнее, чем curl, потому что команды намного компактнее и поддерживается сессия. Поддержка mysql-протокола позволила также сделать поддержку FEDERATED для интеграции Manticore Search c MySQL и Mariadb. Кроме того, Мантикору можно использовать через ProxySQL. HTTP JSON API есть и в Эластике, и в Мантикоре. Logstash, Kibana: Мантикора уже умеет работать с  обоими, но пока в бета/альфа-версии. Скоро доведём эту интеграцию до ума. Вот так можно попробовать Мантикору с Кибаной: И в Эластике и в Мантикоре используется синхронная репликация. Мы не стали изобретать велосипед и интегрировались с библиотекой Galera, которую также используют Mariadb и Percona Xtradb cluster. Важным отличием в управлении репликацией и кластеризацией в Мантикоре и Эластике является то, что в Эластике для этого нужно править конфиг, а в Мантикоре всё делается онлайн. В Мантикоре репликация всегда включена и очень легко подключиться к другой ноде и синхронизироваться с ней: В Мантикоре в отличие от Эластика пока ещё нет автоматического шардирования, но объединение нескольких таблиц в одну для ручного шардирования делается проще, чем в Эластике: Также поддерживается работа и с удалёнными нодами, для этого достаточно указать хост, порт и имя таблицы на удалённом хосте. В Мантикоре главенствует более простой SQL, чем JSON. В Эластике - JSON первичен, SQL вторичен. В Мантикоре есть интерактивные курсы - play.manticoresearch.com . В Эластике нет. Есть гайд по тому, как начать с примерами для разных ОС и языков - https://manual.manticoresearch.com/Quick_start_guide. Есть возможность пообщаться напрямую с разработчиками в публичных каналах: Слак, Телеграм, Форум. Мы даже специально завели короткий созвучный домен mnt.cr и интегрировали его с документацией так, что mnt.cr/<keyword> делает поиск по документации в особом режиме - сразу перематывает на наиболее релевантную секцию. Это особенно удобно, когда нужно вспомнить какие-то детали по какой-то настройке, например mnt.cr/max_packet_size. Kubernetes оператор у Эластика. Helm chart у Мантикоры. В Эластике большинство вещей делаются только через API. Нет возможности дописать в конфиг схемы таблиц (индексов), чтоб они были доступны сразу после запуска. Мантикора, как Kubernetes, поддерживает два режима работы: Императивный: когда всем можно управлять онлайн через CREATE TABLE/DROP TABLE/ALTER TABLE, CREATE CLUSTER/JOIN CLUSTER/DELETE CLUSTER Декларативный: когда можно описать таблицы в конфиге, что даёт более высокую переносимость и более лёгкую возможность интегрировать Manticore в CI/CD, ETL и прочие процессы. Percolate или Persistent Query - это когда в таблице записаны не документы, а запросы, а поиск осуществляется по документам, а не по запросам. Результат поиска - запросы, удовлетворяющие документам. Такой тип поиска полезен для подписок пользователей: подписался, например, пользователь на запрос “Телевизор диагональ > 42” и как только он появился на сайте, то ему про это приходит оповещение. В Мантикоре это есть, как и в Эластике. По нашим тестам пропускная способность такого типа поиска в Мантикоре существенно выше. Сейчас мы развиваем проект по следующим направлениям: Drop-in replacement для Эластика в рамках использования с Logstash и Kibana (Opensearch Dashboards). Хотим, чтоб низкий latency, которого несложно достичь с Мантикорой был доступен людям для анализа логов. У нас уже есть бета. Будем благодарны за фидбэк и баг репорты. Schemaless режим работы. Хотим чтоб про схемы данных не нужно было думать в большинстве случаев. Автоматический шардинг и оркестрирование шардов, чтоб заливать данные в Мантикору можно было ещё быстрее, а шарды расползались по кластеру в оптимальном порядке для большей отказоустойчивости. Дальнейшие оптимизации производительности. Хотим latency ещё ниже, а пропускную способность выше. Таки что мы имеем  Мантикора сейчас может заинтересовать тех: Кому важно низкое время отклика и на малых и на больших объёмах данных. Кто любит SQL. Кто хочет попроще и побыстрее интегрировать поиск в приложение. Кто хочет чего-то более легковесного. Кому важно использовать чистый open source. А мы продолжаем. Поддержать наше начинание можно звездой на Гитхабе https://github.com/manticoresoftware/manticoresearch/ Спасибо, что дочитали!  CEO