1 added
1 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>В этой статье поговорим об архитектуре<strong>быстрого высоконагруженного приложения</strong>на примере сервиса<a>Searchanise</a>. Это облачный сервис, включающий в себя умный поиск, рекомендательную систему, навигацию и инструменты повышения конверсии внутри интернет-магазинов.</p>
1
<p>В этой статье поговорим об архитектуре<strong>быстрого высоконагруженного приложения</strong>на примере сервиса<a>Searchanise</a>. Это облачный сервис, включающий в себя умный поиск, рекомендательную систему, навигацию и инструменты повышения конверсии внутри интернет-магазинов.</p>
2
<h2>О развитии функциональности сервиса</h2>
2
<h2>О развитии функциональности сервиса</h2>
3
<p>В качестве ядра сервиса был использован поисковый движок, угадывающий запрос по первым введённым символам, а также исправляющий ошибки и предлагающий актуальные подсказки. Сам поиск поначалу сопровождался виджетом, в котором отображались продукты с фотографиями, стоимостью, указанием остатка на складе, а также рейтингом. Кроме того, дополнительно показывались контентные страницы и категории, релевантные поисковому запросу.</p>
3
<p>В качестве ядра сервиса был использован поисковый движок, угадывающий запрос по первым введённым символам, а также исправляющий ошибки и предлагающий актуальные подсказки. Сам поиск поначалу сопровождался виджетом, в котором отображались продукты с фотографиями, стоимостью, указанием остатка на складе, а также рейтингом. Кроме того, дополнительно показывались контентные страницы и категории, релевантные поисковому запросу.</p>
4
<p>По мере развития сервиса в нём появились: - рекомендательные блоки; - фильтры; - страница результатов; - промоинструменты; - мерчендайзинг; - аналитика.</p>
4
<p>По мере развития сервиса в нём появились: - рекомендательные блоки; - фильтры; - страница результатов; - промоинструменты; - мерчендайзинг; - аналитика.</p>
5
<h2>Архитектура</h2>
5
<h2>Архитектура</h2>
6
<p>Главное в любой системе - это архитектура. Что касается Searchanise, то он хостится на десяти железных серверах. Используется KVM-виртуализация, где создано маленькое облако, в котором находится более 50 виртуалок. На одном железе располагается около шести серверов, причём каждый из них решает свою задачу: кто-то лишь хранит статистику, а кто-то принимает запросы. Есть отдельные серверы для панели администратора и индексации. Больше всего именно поисковых серверов - 30, т. к. системе<strong>Sphinx</strong>для организации быстрого поиска необходимо много памяти.</p>
6
<p>Главное в любой системе - это архитектура. Что касается Searchanise, то он хостится на десяти железных серверах. Используется KVM-виртуализация, где создано маленькое облако, в котором находится более 50 виртуалок. На одном железе располагается около шести серверов, причём каждый из них решает свою задачу: кто-то лишь хранит статистику, а кто-то принимает запросы. Есть отдельные серверы для панели администратора и индексации. Больше всего именно поисковых серверов - 30, т. к. системе<strong>Sphinx</strong>для организации быстрого поиска необходимо много памяти.</p>
7
<p>В тот момент, когда пользователь устанавливает модуль, он тем самым регистрируется на сервере, после чего начинает отправлять поисковые данные. Эти данные поступают в очередь, а оттуда - в базы данных. Когда импорт данных заканчивается, команда на индексацию поступает в очередь индексации. Что касается обработчиков очереди API, то они расположены на десяти серверах, в то время как обработчики индексации - на 19-ти.</p>
7
<p>В тот момент, когда пользователь устанавливает модуль, он тем самым регистрируется на сервере, после чего начинает отправлять поисковые данные. Эти данные поступают в очередь, а оттуда - в базы данных. Когда импорт данных заканчивается, команда на индексацию поступает в очередь индексации. Что касается обработчиков очереди API, то они расположены на десяти серверах, в то время как обработчики индексации - на 19-ти.</p>
8
<p>Довольно необычно сделаны<strong>очереди</strong>: они реализованы в Redis посредством LUA-скриптов и встроенных в Redis типов данных. Таким образом удалось часть логики переложить в очередь и получить очереди, распараллеливаемые по нужным условиям. Такие очереди способны повторять ошибочные запросы лишь фиксированное число раз, а при падении обработчика потеря данных не происходит.</p>
8
<p>Довольно необычно сделаны<strong>очереди</strong>: они реализованы в Redis посредством LUA-скриптов и встроенных в Redis типов данных. Таким образом удалось часть логики переложить в очередь и получить очереди, распараллеливаемые по нужным условиям. Такие очереди способны повторять ошибочные запросы лишь фиксированное число раз, а при падении обработчика потеря данных не происходит.</p>
9
<p>Для каждой конкретной регистрации создаётся своя база (на момент написания материала их было более 10 тысяч). Да, такое решение не является стандартным, зато у него есть несомненный плюс -<strong>базы реально изолируются</strong>. Согласитесь, что удалить такую базу намного проще и быстрее, чем заниматься вычисткой информации из таблиц. Вдобавок к этому, решается проблема торможения индекса, которая возникает при добавлении или частой работе с обновлениями базы. Нельзя не сказать и то, что если базы отделены, у нас<strong>не возникает проблем с шардированием</strong>. То есть просто раскладывается определенное количество баз на каждый MySQL-сервер.</p>
9
<p>Для каждой конкретной регистрации создаётся своя база (на момент написания материала их было более 10 тысяч). Да, такое решение не является стандартным, зато у него есть несомненный плюс -<strong>базы реально изолируются</strong>. Согласитесь, что удалить такую базу намного проще и быстрее, чем заниматься вычисткой информации из таблиц. Вдобавок к этому, решается проблема торможения индекса, которая возникает при добавлении или частой работе с обновлениями базы. Нельзя не сказать и то, что если базы отделены, у нас<strong>не возникает проблем с шардированием</strong>. То есть просто раскладывается определенное количество баз на каждый MySQL-сервер.</p>
10
<p>Что касается приложения для<strong>Shopify</strong>, то оно написано на Erlang. Этот язык оказался весьма быстрым и удобным для решения задач параллельного программирования. В частности, его использование позволяет поддерживать тысячи магазинов, осуществляя по<strong>несколько миллионов запросов к API</strong>. К слову, Shopify имеет очень развитый API, с которым возможно делать почти всё. В результате была сделана индексация, отслеживание обновлений и статусов магазинов и т. п. Само приложение изолировано - это сделано для соблюдения общей монолитной структуры и сохранения единого API для всех платформ.</p>
10
<p>Что касается приложения для<strong>Shopify</strong>, то оно написано на Erlang. Этот язык оказался весьма быстрым и удобным для решения задач параллельного программирования. В частности, его использование позволяет поддерживать тысячи магазинов, осуществляя по<strong>несколько миллионов запросов к API</strong>. К слову, Shopify имеет очень развитый API, с которым возможно делать почти всё. В результате была сделана индексация, отслеживание обновлений и статусов магазинов и т. п. Само приложение изолировано - это сделано для соблюдения общей монолитной структуры и сохранения единого API для всех платформ.</p>
11
<p>Теперь о<strong>метриках</strong>. Они собираются со всех серверов с помощью Zabbix. Чрезвычайно удобно - знать, что с сервером происходит, насколько он загружен. Кроме того, в Zabbix настроены триггеры на различные "внештатные" ситуации - когда что-то идёт не так, приходит уведомление на почту и в Slack.</p>
11
<p>Теперь о<strong>метриках</strong>. Они собираются со всех серверов с помощью Zabbix. Чрезвычайно удобно - знать, что с сервером происходит, насколько он загружен. Кроме того, в Zabbix настроены триггеры на различные "внештатные" ситуации - когда что-то идёт не так, приходит уведомление на почту и в Slack.</p>
12
<h2>Работа со Sphinx</h2>
12
<h2>Работа со Sphinx</h2>
13
-
<p>За счёт Sphinx и проведённой оптимизации скорость поиска сервиса Searchanise значительно превысило конкурирующие предложения. ��апример, сервис без проблем поддерживает 500 тысяч продуктов в поиске при ежедневной обработке порядка 15 миллионов поисковых запросов.</p>
13
+
<p>За счёт Sphinx и проведённой оптимизации скорость поиска сервиса Searchanise значительно превысило конкурирующие предложения. Например, сервис без проблем поддерживает 500 тысяч продуктов в поиске при ежедневной обработке порядка 15 миллионов поисковых запросов.</p>
14
<p>Да, у Sphinx, есть проблемы, многие их которых удалось обойти. Многие, но не все: Sphinx периодически падает, и поделать с этим пока ничего нельзя. Для подстраховки приходится один индекс держать на 2-х серверах: если Sphinx упадёт на одном, обслуживание запросов обеспечит второй.</p>
14
<p>Да, у Sphinx, есть проблемы, многие их которых удалось обойти. Многие, но не все: Sphinx периодически падает, и поделать с этим пока ничего нельзя. Для подстраховки приходится один индекс держать на 2-х серверах: если Sphinx упадёт на одном, обслуживание запросов обеспечит второй.</p>
15
<h2>Тестирование</h2>
15
<h2>Тестирование</h2>
16
<p>Unit-тестирование не используется, ведь если система быстро развивается, поддерживать unit-тесты в актуальном состоянии - значит существенно тормозить процесс разработки.</p>
16
<p>Unit-тестирование не используется, ведь если система быстро развивается, поддерживать unit-тесты в актуальном состоянии - значит существенно тормозить процесс разработки.</p>
17
<p>При этом все метрики проверяются самописными короткими тестами, плюс используются функциональные тесты для API. Так как API является фиксированным, тесты часто менять не приходится. Да и вообще, в данном случае функциональное тестирование эффективнее, чем регулярная правка unit-тестов под постоянно меняющиеся требования.</p>
17
<p>При этом все метрики проверяются самописными короткими тестами, плюс используются функциональные тесты для API. Так как API является фиксированным, тесты часто менять не приходится. Да и вообще, в данном случае функциональное тестирование эффективнее, чем регулярная правка unit-тестов под постоянно меняющиеся требования.</p>
18
<h2>Виджеты</h2>
18
<h2>Виджеты</h2>
19
<p>На ряде платформ результаты поиска отображаются в дизайне платформы. Кроме того, на некоторых платформах поиск показывается в JS-виджетах. Управление всем этим осуществляется через встраиваемую админку, которая тоже представляет собой JS-виджет.</p>
19
<p>На ряде платформ результаты поиска отображаются в дизайне платформы. Кроме того, на некоторых платформах поиск показывается в JS-виджетах. Управление всем этим осуществляется через встраиваемую админку, которая тоже представляет собой JS-виджет.</p>
20
<p>Вообще, для системы виджетов предусмотрено большое число всевозможных настроек. Все они обновляются почти в реальном времени (оказываются у клиента в течение 10-20 секунд). У аналогичных конкурирующих сервисов этот показатель достигает 10-15 минут, как говорится, результат налицо.</p>
20
<p>Вообще, для системы виджетов предусмотрено большое число всевозможных настроек. Все они обновляются почти в реальном времени (оказываются у клиента в течение 10-20 секунд). У аналогичных конкурирующих сервисов этот показатель достигает 10-15 минут, как говорится, результат налицо.</p>
21
<p>Файлы виджетов хранятся на Amazon S3, но раздаются они не напрямую, а посредством CDN. Точнее, KeyCDN - это недорого, прекрасно работает, плюс изменения быстро актуализируются, а IP-адреса не заблокированы ни в одной из стран мира.</p>
21
<p>Файлы виджетов хранятся на Amazon S3, но раздаются они не напрямую, а посредством CDN. Точнее, KeyCDN - это недорого, прекрасно работает, плюс изменения быстро актуализируются, а IP-адреса не заблокированы ни в одной из стран мира.</p>
22
<h2>Выводы</h2>
22
<h2>Выводы</h2>
23
<p>Благодаря использованию системы Sphinx, был построен сервис поиска для множества пользователей и с обеспеченной себестоимостью почти в 10 раз ниже, чем у конкурирующих компаний. Правда, Sphinx из коробки не очень удобен. Это проявляется, например, при попытках использовать его со множеством индексов и при организации на его основе распределённого сервиса. В результате пришлось преодолеть множество сложностей и придумать ряд уникальных решений - только тогда удалось наладить процесс индексации, распараллеливания и faleover.</p>
23
<p>Благодаря использованию системы Sphinx, был построен сервис поиска для множества пользователей и с обеспеченной себестоимостью почти в 10 раз ниже, чем у конкурирующих компаний. Правда, Sphinx из коробки не очень удобен. Это проявляется, например, при попытках использовать его со множеством индексов и при организации на его основе распределённого сервиса. В результате пришлось преодолеть множество сложностей и придумать ряд уникальных решений - только тогда удалось наладить процесс индексации, распараллеливания и faleover.</p>
24
<p><em>За<a>материал</a>выражается благодарность Дмитрию Сухоносову, руководителю разработки в Searchanise.</em></p>
24
<p><em>За<a>материал</a>выражается благодарность Дмитрию Сухоносову, руководителю разработки в Searchanise.</em></p>
25
25