Как разрабатывается умный поиск — нюансы и сложности
Разбираем архитектуру высоконагруженного сервиса, который включает умный поиск, рекомендательную систему, инструменты повышения конверсии и не только.
6К открытий6К показов
Дмитрий Сухоносов
руководитель разработки в <a href="https://start.searchanise.com/">Searchanise</a>
Всем привет! Меня зовут Дима, я занимаюсь разработкой 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К показов