Написать пост

Как разрабатывается умный поиск — нюансы и сложности

Аватар Типичный программист

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

Всем привет! Меня зовут Дима, я занимаюсь разработкой Searchanise — это облачный сервис для поиска товаров и повышения конверсии внутри интернет-магазинов.

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

Как развивалась функциональность сервиса

Ядро сервиса — это поисковый движок, который угадывает запрос по первым введённым символам, исправляя ошибки и предлагая наиболее актуальные подсказки. Поиск сопровождается виджетом, где отображаются продукты с изображениями, ценой, остатком на складе, рейтингом, а также релевантные поисковому запросу контентные страницы, категории и подсказки.

Новые опции появлялись по мере сотрудничества с платформами. Когда мы приходили на новую платформу, то понимали, какой функциональности не хватает. Так появилась страница результатов поиска, фильтры, рекомендательные блоки, мерчендайзинг, промоинструменты, аналитика. Потом мы поняли, что клиентам нужны рекомендации и начали развиваться в этом направлении. Чтобы рекомендации хорошо работали, в планах развивать персонализацию поиска и внедрять машинное обучение.

Архитектура

Главное в системе — это архитектура. В нашем случае — доработка архитектуры с целью повышения скорости.

Хостимся на 10 железных серверах. Используем виртуализацию KVM, создали свое маленькое облако, в котором у нас больше 50 виртуалок. На одном железе — примерно 6 серверов, каждый из которых отвечает за что-то своё: какой-то принимает запросы, какой-то только хранит статистику, отдельный сервер для админки, отдельный сервер для индексации. Больше всего поисковых серверов — 30, так как Sphinx для организации быстрого поиска требуется много памяти.

Когда клиент устанавливает модуль, он регистрируется на сервере и начинает отправлять данные для поиска. Все эти данные попадают в очередь, а из неё — в базы данных. После того как импорт данных закончен, команда на индексацию попадёт в очередь индексации. Обработчики очереди API у нас расположены на 10 серверах, а обработчики индексации — на 19 серверах.

Очереди сделаны очень необычно: мы реализовали их сами в Redis с помощью LUA скриптов и встроенных в Redis типов данных. Получилось хорошо: мы смогли часть логики переложить в очередь и получили очереди, которые распараллеливаются по нужным нам условиям. Ещё наши очереди умеют повторять ошибочные запросы только фиксированное число раз и при падении обработчика данные не теряются.

Для каждой регистрации создается своя база — на данный момент у нас их 10 000. Это нестандартное решение, у которого есть огромное преимущество — мы реально изолируем базы. Удалить базу гораздо проще, чем вычищать информацию из таблиц. Помимо этого, решается еще одна проблема: при добавлении или частой работе с обновлениями базы, индекс тормозит. Когда базы отделены, не возникает проблем с шардированием. Просто раскладываем определенное число баз на каждый сервер Mysql.

Приложение для Shopify написано на Erlang, который оказался очень быстр и удобен для задач параллельного программирования: с его помощью не проблема поддерживать тысячи магазинов, делая по несколько миллионов запросов к API. У Shopify очень развитое API, с которым можно делать практически всё. С помощью API мы сделали индексацию, следим за обновлениями, статусами магазинов и т.д. Приложение изолировано для того, чтобы соблюсти общую монолитную структуру и иметь единый API для всех платформ.

Со всех серверов собираем метрики с помощью Zabbix. Это очень удобно — в каждый момент знать что происходит с сервером и насколько он загружен. Также в Zabbix настроены триггеры на разные «внештатные» ситуации — если что-то пойдет не так, придёт уведомление в Slack и на почту.

Работа со Sphinx

Благодаря Sphinx и тому, что мы много времени потратили на оптимизацию, скорость поиска Searchanise во много раз выше конкурирующих предложений — мы легко поддерживаем 500 000 продуктов в поиске. И эта возможность дана Sphinx. Ежедневно мы обрабатываем 15 млн поисковых запросов.

Но мы знаем и о проблемах Sphinx, и многие уже научились обходить. Но осталась одна: Sphinx периодически падает и с этим пока ничего не получается поделать. Поэтому мы один индекс держим на двух серверах: если Sphinx упадёт на одном, второй будет обслуживать запросы.

Тестирование

Мы не используем unit-тестирование. Когда система быстро развивается, поддержка unit-тестов в актуальном состоянии сильно тормозит процесс разработки.

Все метрики проверяем самописными короткими тестами; используем функциональные тесты для API. API у нас фиксировано и тесты не приходится часто менять.Считаем, что функциональное тестирование эффективнее регулярной правки unit-тестов под меняющиеся требования.

Виджеты

На некоторых платформах результаты поиска показываются в дизайне платформы. На других платформах (например Shopify) поиск отображается в JS-виджетах. Всё это управляется нашей встраиваемой админкой, которая тоже JS-виджет.

У нас огромное количество настроек для системы виджетов. Все настройки обновляются практически в режиме реального времени (в течение 10–20 секунд оказываются у клиента). У конкурентов иногда приходится ждать 10–15 минут.

Файлы виджетов мы храним на Amazon S3, но раздаем не напрямую, а используем CDN. Мы используем KeyCDN: недорого, хорошо работает, изменения быстро актуализируются, IP-адреса не заблокированы ни в одной стране.

Вывод

За счёт использования Sphinx мы построили сервис поиска для множества клиентов и обеспечили себестоимость практически в 10 раз ниже, чем у конкурентов. Но Sphinx из коробки очень неудобен. Неудобно его использовать со множеством индексов и организовать на его основе распределенный сервис. Нам пришлось преодолеть много трудностей и придумать много уникальных решений для налаживания процесса индексации, распараллеливания и faleover.

Следите за новыми постами
Следите за новыми постами по любимым темам
6К открытий6К показов