Миллионы объявлений на площадке имеют смысл только тогда, когда покупатели могут быстро найти среди них нужное.
KupujemProdajem — крупнейшая площадка объявлений в Сербии. Для пользователей поиск — один из главных способов найти нужный товар: им пользуются и на сайте, и в мобильных приложениях. Сотрудникам поиск тоже нужен для модерации и работы службы поддержки. Поэтому от релевантности и скорости ответа напрямую зависят и вовлечённость пользователей, и то, насколько легко покупатели находят объявления продавцов.
Сегодня KupujemProdajem использует Manticore Search для поиска примерно по 5,6 миллиона активных объявлений, а отдельные внутренние индексы содержат около 70 миллионов строк актуальных и исторических данных. Продакшен-кластер в среднем обрабатывает около 150 поисковых запросов в секунду, а Manticore отвечает на запрос примерно за 10 мс.
На той же поисковой инфраструктуре команда теперь может решать более сложную задачу — внедрять гибридный поиск , который объединит лексический и семантический поиск с учётом особенностей сербского языка и самих объявлений.
Поиск — одна из главных функций продукта
В KupujemProdajem два основных типа поисковых индексов. Первый обслуживает пользовательский поиск. В нём около 5,6 миллиона активных объявлений: заголовки, описания, категории и структурированные атрибуты. Именно по этим данным пользователи ищут на сайте и в мобильных приложениях.
Второй набор индексов нужен внутренним командам. Помимо актуальных данных, в нём хранится часть истории удалённых объявлений, поэтому модераторы и служба поддержки могут находить информацию, которой уже нет в публичной части площадки.
В итоге поиск важен и для пользователей, и для сотрудников. Покупателям он помогает быстро перейти от общего запроса к подходящему объявлению, продавцам — показывать свои предложения заинтересованным людям, а сотрудникам — находить исторические данные при разборе спорных ситуаций.
Как говорит Димитрие Маринкович , бэкенд-разработчик KupujemProdajem:
«Поиск — основной способ находить объявления на площадке. Поэтому от релевантности и скорости ответа напрямую зависят вовлечённость пользователей и то, насколько успешно продавцы находят покупателей».
Как выбирали поисковый движок для растущей площадки объявлений
KupujemProdajem много лет использовал выделенный поисковый движок. Раньше это был Sphinx Search . Когда он перестал активно развиваться, команде понадобилась альтернатива с активной поддержкой, которую можно было встроить в существующую архитектуру без полной переделки поисковой интеграции.
Но одной совместимости было недостаточно. Новый движок должен был:
- обеспечивать стабильно низкую задержку;
- обновлять миллионы объявлений в реальном времени ;
- поддерживать репликацию ;
- давать SQL-интерфейс , совместимый с PHP-стеком команды, построенным вокруг MySQL;
- совмещать полнотекстовый поиск с фильтрацией по структурированным атрибутам ;
- позволять гибко настраивать релевантность ;
- оставлять возможность в будущем добавить векторный и гибридный поиск .
В Manticore всё это есть в одном движке. И последний пункт со временем становится всё важнее.
KupujemProdajem планирует дополнить традиционный лексический поиск векторным на базе собственной модели эмбеддингов . Manticore поддерживает и KNN-поиск , и полнотекстовый поиск в одном движке, поэтому эту функцию можно будет добавить в существующую инфраструктуру без отдельной векторной базы и синхронизации данных с ней.
Миллионы объявлений обновляются в реальном времени
MySQL по-прежнему остаётся основным источником данных площадки. Когда объявление создают, изменяют или удаляют, Manticore сразу получает соответствующее обновление. В продакшене в среднем выполняется около 40 операций REPLACE
в секунду, а также операции UPDATE
и DELETE
.
Для площадки объявлений это особенно важно: данные меняются постоянно. Продавцы публикуют новые предложения, обновляют цены и описания, меняют статус объявлений и удаляют товары, которых больше нет в наличии.
Поэтому от поисковой системы одновременно нужны две вещи:
- быстро находить релевантные результаты;
- показывать актуальное состояние площадки.
Обновления идут в реальном времени, поэтому поисковый индекс Manticore остаётся синхронизирован с MySQL.
Поиск — это не только слова
Искать по объявлениям сложнее, чем по обычным документам. Помимо текста, у каждого объявления есть структурированные данные: категория, цена, местоположение, статус и другие свойства. В Manticore KupujemProdajem совмещает полнотекстовый поиск с фильтрацией по этим атрибутам.
Команда сама задаёт, насколько сильно разные части объявления влияют на релевантность. Например, заголовок имеет гораздо больший вес, чем описание или категория. Для объявлений это естественно: точное название товара в заголовке обычно намного важнее, чем то же слово где-то в длинном описании.
Кроме того, KupujemProdajem использует собственный ранкер , настроенный под свои требования к релевантности, и группирует результаты по объявлениям. Это позволяет учитывать особенности площадки, а не полагаться только на универсальную формулу ранжирования.
Небольшой кластер с репликацией
Manticore работает на четырёх виртуальных машинах. Три ноды образуют продакшен-кластер с репликацией, четвёртая используется как резервная. Все записи идут на одну ноду и реплицируются на остальные, а запросы на чтение приложение распределяет между всеми тремя продакшен-нодами.
Архитектура выглядит довольно просто: MySQL → обновления в реальном времени → нода Manticore для записи → реплики Manticore → поиск на сайте, в мобильном приложении и админке
Такую схему несложно поддерживать. Команде не приходится разворачивать большую распределённую платформу только ради поиска по объявлениям. Один кластер принимает обновления, выполняет полнотекстовый поиск, фильтрацию и собственное ранжирование, поддерживает репликацию и в будущем сможет взять на себя ещё и векторный поиск.
5,6 миллиона активных объявлений и 70 миллионов строк во внутренних индексах
Пользовательские индексы сейчас содержат около 5,6 миллиона активных объявлений и занимают примерно 9 ГБ. Более крупные внутренние индексы содержат около 70 миллионов строк, в том числе исторические данные о части удалённых объявлений, и занимают примерно 90 ГБ.
Основные показатели продакшен-кластера из трёх нод:
| Метрика | Значение в продакшене |
|---|---|
| Активные объявления | ~5,6 миллиона |
| Строки во внутренних индексах | ~70 миллионов |
| Размер пользовательских индексов | ~9 ГБ |
| Размер внутренних индексов | ~90 ГБ |
| Поисковая нагрузка | ~150 запросов/с в среднем |
| Поисковая нагрузка на ноду | ~50 запросов/с в среднем |
Операции REPLACE | ~40 операций/с |
| Среднее время запроса | ~10 мс |
| Инфраструктура | 3 виртуальные машины в продакшене + 1 резервная |
При обычной нагрузке кластер работает стабильно: зависших и долгих запросов нет. Иногда время ответа ненадолго вырастает примерно до 150 мс, но в среднем остаётся около 10 мс. Это не синтетический бенчмарк, а показатели реальной продакшен-нагрузки, на которой работает основной поиск крупной площадки объявлений.
Что эта архитектура даёт пользователям
Сами по себе инфраструктурные метрики мало что значат — важен результат для пользователей. Manticore быстро ищет по миллионам объявлений с учётом настроек релевантности и фильтров по атрибутам. Все изменения сразу попадают в индекс, поэтому результаты отражают актуальное состояние площадки без регулярной полной переиндексации.
Для продавцов поиск остаётся основным каналом, через который покупатели находят их объявления. А модераторы и служба поддержки могут искать по гораздо более крупным внутренним индексам и находить исторические данные даже по объявлениям, которых уже нет в публичной части площадки.
Следующий шаг — лучше понимать запросы на сербском языке
Следующий проект команды KupujemProdajem — гибридный поиск . Традиционный полнотекстовый поиск лучше всего работает, когда в запросе есть те же слова, что и в объявлении. Но покупатель и продавец могут описывать один и тот же товар совершенно по-разному.
С сербским языком задача становится ещё сложнее. Команде нужно учитывать:
- богатую морфологию ;
- два алфавита — латиницу и кириллицу;
- синонимы ;
- то, что покупатели и продавцы по-разному описывают один и тот же товар.
Поэтому KupujemProdajem готовит собственную модель эмбеддингов для объявлений на сербском языке. Идея такая: выполнять лексический поиск и KNN-поиск по векторам, а затем объединять их результаты прямо во время запроса.
Покупатель может искать товар словами, которых вообще нет в объявлении продавца, хотя само объявление ему подходит. Семантический поиск как раз помогает связать такой запрос с нужным предложением.
Димитрие формулирует ожидаемый результат так:
«Семантический поиск поможет пользователям находить подходящие объявления, даже если в запросе нет тех же слов, что и в самом объявлении».
Для инженерной команды важен и другой момент: не нужно добавлять ещё одну базу данных. Векторы можно хранить рядом с текстом и структурированными атрибутами, которые уже доступны для поиска в Manticore. Тогда один движок сможет одновременно учитывать лексическую релевантность, фильтры и семантическую близость.
Основа для дальнейшего развития поиска
KupujemProdajem уже использует Manticore в одном из самых важных процессов на площадке: в поиске доступны примерно 5,6 миллиона активных объявлений, а среднее время запроса к движку составляет около 10 мс. Обновления идут непрерывно, репликация даёт несколько поисковых нод, а внутренние команды используют ту же технологию для поиска по гораздо большему объёму исторических данных.
Следующий этап — эксперименты с семантическим поиском и гибридным ранжированием. Для этого команде не придётся менять поисковую инфраструктуру или обслуживать отдельную векторную базу данных.
Сегодня Manticore уже обеспечивает KupujemProdajem быстрый поиск по актуальному каталогу и при этом оставляет команде понятный путь для дальнейшего улучшения поиска.

