[Перевод] Как работает поиск в SaaS Kiva, где у каждого клиента своя база данных

Как работает поиск в SaaS Kiva, где у каждого клиента своя база данных
В SaaS-платформе, которую клиенты настраивают с помощью low-code/no-code-инструментов, трудно заранее знать, по каким именно данным пользователи захотят искать. Один клиент добавляет свои поля и формы, другой настраивает собственные бизнес-процессы, третий использует найденные данные для фильтрации, массового редактирования или маркетинговых кампаний.
С такой задачей столкнулась Kiva Teknoloji — турецкая компания, которая с 2009 года разрабатывает облачные бизнес-приложения. Её основной продукт, KivaCRM, построен на собственной Kiva Cloud Platform и сочетает CRM с инструментами для автоматизации бизнес-процессов, отчётности и аналитики. Клиенты могут сами настраивать формы, списки, процессы, отчёты и панели управления, поэтому одна и та же платформа используется компаниями из более чем 40 отраслей.
Такая гибкость напрямую влияет на поиск. У каждого клиента Kiva своя база данных, а структура таблиц меняется по мере того, как клиент настраивает приложение под свои процессы. Поэтому нельзя один раз настроить поиск под фиксированный набор полей и больше его не менять.
Manticore Search здесь работает как отдельный поисковый слой рядом с MySQL. Он отвечает за полнотекстовый поиск, а MySQL остаётся основной базой данных. Такой подход позволил Kiva разгрузить основные серверы БД, добавить более гибкие возможности поиска и при этом почти не увеличить расходы на инфраструктуру.
Поиск — часть платформы, а не просто строка поиска
Kiva индексирует самые разные данные, которые клиенты создают в своих приложениях. Поиск доступен в разных разделах продукта, а найденные записи используют не только для просмотра.
По словам Арды Беязоглу, ведущего инженера Kiva Teknoloji, поиск используется для аналитики, фильтрации, массового редактирования записей, email- и SMS-кампаний и других задач.
«Мы используем Manticore для полнотекстового поиска и индексируем самые разные данные, которые создают наши клиенты».
Это не обычный поиск по каталогу с заранее заданной схемой. У каждого клиента Kiva отдельная база данных, а её структура зависит от того, как настроено приложение. По мере кастомизации появляются новые поля и сущности.
Поэтому поисковый слой должен подстраиваться под данные каждого клиента, а не под одну заранее определённую модель.
Почему полнотекстового поиска в MySQL оказалось недостаточно
До перехода на Manticore Kiva использовала встроенный полнотекстовый поиск MySQL.
По словам Арды, он работал медленнее Manticore и отнимал ресурсы у основного сервера базы данных. Для SaaS это особенно чувствительно: те же CPU и память нужны самому приложению, а поиск начинает конкурировать с его рабочей нагрузкой.
Поэтому Kiva вынесла полнотекстовый поиск в отдельный слой, вместо того чтобы заставлять MySQL одновременно обслуживать основную нагрузку и выполнять поиск.
При этом MySQL остался основным хранилищем данных, а Manticore взял на себя поиск по ним.
Почему Kiva перешла на Manticore
До Manticore команда некоторое время использовала Sphinx. Позже Kiva перешла на Manticore из-за проблем с совместимостью версий и более медленного развития прежнего решения. При этом существующую схему работы с поиском удалось сохранить.
Своя поисковая таблица для каждого клиента
Сейчас схема выглядит так:
MySQL клиента → поисковый кэш → периодически перестраиваемая таблица + RT-таблица → распределённая таблица Manticore → поиск → ID записей → MySQL
Для каждой таблицы с пользовательскими данными Kiva формирует поисковый кэш. Затем для каждого клиента создаётся своя распределённая таблица Manticore.
Она объединяет две локальные таблицы:
одну полностью перестраивают раз в неделю;
в RT-таблицу попадают изменения в реальном времени.
Так пользователи ищут по актуальным данным, а Kiva не приходится постоянно перестраивать всю поисковую таблицу.
Когда пользователь что-то ищет в приложении, Manticore находит подходящие записи. Затем приложение делает точечные запросы к исходным таблицам MySQL, чтобы получить остальные данные.
Это позволяет не дублировать в Manticore всё содержимое исходных таблиц. Для поиска достаточно получить ID подходящих записей, а остальные данные приложение забирает из MySQL.
В итоге каждая система занимается своей задачей:
MySQL хранит исходные данные приложения;
Manticore отвечает за поиск;
приложение по ID связывает результаты поиска с исходными записями.
Отдельные серверы для поиска не понадобились
Объём данных у клиентов Kiva сильно различается: платформой пользуются и небольшие компании, и крупные предприятия.
Арда приводит такие ориентиры:
Показатель | Значение |
|---|---|
Размер большинства таблиц | до нескольких ГБ |
Несколько крупных таблиц | 30 ГБ и больше |
Полное построение небольших таблиц | до нескольких минут |
Полное построение крупных таблиц | примерно 30–60 минут |
Отдельный сервер для Manticore | Kiva не использует |
Последний пункт особенно показателен.
В Kiva не выделяют для Manticore отдельные серверы. Поисковый движок запускают либо на сервере приложения, либо на сервере с репликой базы данных.
«Мы никогда не выделяем Manticore отдельный сервер. В простое он потребляет очень мало ресурсов и эффективно использует CPU, поэтому при нашем масштабе дополнительные расходы на инфраструктуру практически нулевые».
Для Kiva это означает, что отдельный поисковый слой не обернулся ещё одним кластером, который нужно оплачивать и обслуживать.
Меньше нагрузки на MySQL, больше ресурсов для приложения
Главный результат для Kiva — не только более быстрый полнотекстовый поиск.
После переноса поисковой нагрузки из MySQL у серверов базы данных освободились ресурсы. Их можно использовать для более важных данных и операций приложения, а та же инфраструктура теперь позволяет обслуживать больше клиентов.
Кроме того, Manticore дал Kiva возможности, которых раньше не хватало: более развитые способы поиска и поддержку разных языков.
Следующий шаг — гибридный поиск
Kiva рассматривает Manticore и для новых приложений с AI-функциями.
По словам Арды, команда думает об использовании гибридного поиска, который сочетает полнотекстовый и векторный поиск. Для Kiva это продолжение уже существующей архитектуры: Manticore и сейчас служит поисковым слоем для данных клиентов, поэтому новые способы поиска можно добавить туда же, не перенося исходные данные из MySQL.
Пока это только планы, а не то, что уже работает в продакшене. Но это показывает, как поисковый слой может развиваться дальше — от полнотекстового поиска к поиску, который учитывает и слова, и смысл запроса.
Поиск по данным с меняющейся структурой
В Kiva Manticore встроен в существующую инфраструктуру и не требует отдельного поискового кластера.
У каждого клиента своя база данных и своя схема, которая меняется по мере настройки приложения. Manticore объединяет периодически перестраиваемую таблицу с изменениями из RT-таблицы и возвращает ID найденных записей. MySQL при этом остаётся основным хранилищем данных.
В результате Kiva сняла полнотекстовую нагрузку с основной базы, стала эффективнее использовать существующие серверы и сделала поиск общей функцией платформы — даже если заранее неизвестно, какие поля и сущности создаст следующий клиент.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.