Как увеличить производительность сайта в несколько раз с помощью Elasticsearch

Тимлид eCommerce-агентства Aero Юрий Кононов о том, как спасти товарный каталог, если он тормозит и грозит рухнуть.

Как увеличить производительность сайта в несколько раз с помощью Elasticsearch

"Позавчера в 13 часов перестроение фасетных индексов вызвало критическую нагрузку и последующее падение сервера app2, что в свою очередь привело к недоступности сайта для ограниченной части пользователей.

Как увеличить производительность сайта в несколько раз с помощью Elasticsearch

На скриншоте можно видеть, что сервер был недоступен в интервале с 13 часов 25 октября до 9 часов 26 октября. Причины выхода нагрузки за пределы допустимой были выявлены на прошлой неделе и 26-27 числа мы продолжили работы по их устранению". Такое письмо мы, разработчики Aero, отправили в компанию Kari после падения сайта kari.com.

Через три дня мы уже смогли написать клиенту: «Нагрузка полностью стабилизирована, отрабатывается 100% входящих запросов, импорты переведены в штатный режим».

Конечно же, мы не разработали с нуля новый функционал за три дня. Эта работа началась за пару месяцев до драматического события.

Что же произошло между этими сообщениями и как нам удалось вернуть сайт к жизни (и даже еще лучшей, чем прежде)? Об этом расскажем в нашем кейсе.

Почему рухнул сайт?

Причина падения сайта Kari — перестроение фасетных индексов «1С-Битрикс». Если коротко, фасетный индекс — это готовый поисковый набор товаров по значению свойства.

Например, нам нужно найти все товары, отфильтрованные по определенной цене. Без фасетного индекса нужно будет получить все товары, у которых торговые предложения находятся в этом ценовом диапазоне. С учетом архитектуры «Битрикса», это большой запрос. В случае с фасетным индексом — мы получаем уже готовую выборку товаров. Подробнее можно почитать здесь.

Время работы фильтра в разделе каталога с 10 000 элементов, в подразделах с 3 000 товаров и 100 товарами, в секундах
Время работы фильтра в разделе каталога с 10 000 элементов, в подразделах с 3 000 товаров и 100 товарами, в секундах

Фасетный индекс – это и хорошо, и плохо. Хорошо, потому что быстро отрабатываются запросы, быстро работает фильтр. Плохо, потому что пересоздание фасеты большого каталога занимает много времени и ресурсов сервера.

В момент пересоздания фасеты сайт Kari сильно тупил, а само пересоздание занимало до 8 часов. Еще пропадало меню, так как оно было основано на фасетах. Эти проблемы давали о себе знать и до падения сайта, и к моменту падения сайта мы уже начали работы по модернизации и оптимизации каталога и всех систем в целом.

О проекте Kari

Kari — это российский обувной ритейлер, лидер в своем сегменте. Работает с 2012 года. Сегодня в сети Kari около 900 розничных торговых точек в четырех странах, а оборот в 2016 году составил более 30 млрд рублей.

Как увеличить производительность сайта в несколько раз с помощью Elasticsearch

Интернет-магазин kari.com работает под высокой нагрузкой:

  • около 100 тысяч визитов в день
  • несколько сотен одновременных соединений
  • более 70 тысяч товаров и 120 тысяч торговых предложений для каждой страны
  • более 30 сервисов
  • обмен с более чем 20 различными системами
Серверная архитектура kari.com
Серверная архитектура kari.com

Переход на Elasticsearch

После падения сайта мы решили отказаться от фасетных индексов и перевели каталог на Elasticsearch. В итоге у нас получилась довольно сложная, но шустрая система.

Структура данных в Elasticsearch

Поскольку сайт мультиязычный, то и хранение товаров должно быть разделено по языкам. Что и было сделано: один индекс (аналог базы данных MySQL) — это одна страна.

Каждая страна содержит в себе тип «товары» и тип «торговые предложения» (аналог таблиц в MySQL). Значения свойств товаров и торговых предложений в Elasticsearch уже полностью подготовлены для вывода на сайте.

Например, при стандартной работе «Битрикса», чтобы получить цену товара для конкретного города, нужно сделать несколько запросов к разным таблицам. А в Elasticsearch эта цена уже готова. Ее нужно просто получить и вывести на экран.

Цену мы формируем в «фоновом» режиме, не заставляя пользователя ждать. Реализуется это через сервис синхронизации данными между Elasticsearch и «1С-Битрикс».

В Elasticsearch не хранятся все свойства товаров, а только системные, без которых не обойтись, а также свойства с пометкой «Умный фильтр», для вывода в фильтре. В свою очередь в фильтре отображаются не все свойства, а только те, которые есть у текущих товаров в разделе. Это сделано при помощи агрегаций — аналога группировок в MySQL. Например, мы хотим знать, какие цвета есть у товаров в разделе? Механизм агрегаций выдает нам эти данные, и далее мы выводим их в фильтре.

Структура данных
Структура данных

Синхронизация данных

Первая проблема, с которой мы столкнулись в этом кейсе — как сделать грамотную синхронизацию данных. Нас спасла система очередей и создание модуля синхронизации данных между «Битриксом» и Elasticsearch.

В результате синхронизация работает следующим образом:

Как увеличить производительность сайта в несколько раз с помощью Elasticsearch

Цены, свойства товаров, остатки, торговые предложения — все хранится в «Битриксе» стандартно. В момент изменения товара на сайте, мы добавляем id этого товара в таблицу очередей. Каждую минуту запускается скрипт, который получает набор id-шников и формирует нужные нам данные — цены, остатки, свойства и т.д. Данные формируются сразу для всех регионов. Далее подготовленный массив данных добавляется в Elasticsearch. Индексация происходит очень быстро. С момента добавления в индекс поиск в Elasticsearch по товару работает уже менее чем через 1 секунду. Ну а потом идет чистка тегированного кэша, чтобы данные были всегда актуальны.

Подобную систему очередей мы используем во многих функциональных блоках сайта. Например, каждые 15 минут выгружается дельта по остаткам товаров. Остатки обновляются, и товар опять попадает в очередь на переиндексацию в Elasticsearch, если его там еще нет.

Система очередей
Система очередей

Система очередей увеличивает время обновления данных о товаре. Но во-первых, это позволяет снять пиковую нагрузку. Страшно представить, что будет, если одновременно начнут переиндексироваться товары, обновляться остатки и т.д. Одних только дельт остатков может приходить до 40 000 за 15 минут. А во-вторых, среднее время обновления информации о товаре на сайте не превышает 7 минут, что не оказывает влияния на функционал каталога.

Детальная карточка товара работает стандартно, на функционале «Битрикса». Это позволяет избежать недостоверных данных о товаре в момент покупки.

Переиндексация

Ежедневно весь индекс по каждой стране полностью обновляется. Напомню, что переиндексация занимает менее 1 часа. И сначала, как и при использовании фасет, частично пропадало меню. Связано это было все с теми же причинами — меню отображалось в зависимости от наличия товаров в том или ином разделе. Нет товаров в разделе — нет меню. А часть товаров недоступна, пока идет полный переиндекс.

Эту проблему мы решили с помощью Alias, псевдонима, который есть в Elasticsearch. По псевдониму можно получить несколько индексов. Перед полной переиндексацией мы создаем временный индекс, который наполняем товарами. На сайте в это время работает старый индекс. Как только временный индекс наполняется, переключаем на него псевдоним, и он становится активным. Все запросы уже идут к нему. А тот, что был до него, удаляется.

И так ежедневно. Это позволяет не терять меню и каталог в момент переиндексации.

Переключение активных и временных индексов
Переключение активных и временных индексов

Вывод данных

Нам пришлось почти полностью переписать стандартные компоненты каталога kari.com, так как они были созданы для работы на стандартном функционале «Битрикса».

Мы создали 5 новых компонентов:

  1. Меню сайта (bitrix.menu)
  2. Список товаров раздела (catalog.section)
  3. Умный фильтр (catalog.smart.filter)
  4. Карта сайта (sitemap)
  5. Поиск (search)

На вход компонентов приходит массив данных из Elasticsearch, который обрабатывается с помощью стандартного функционала «Битрикса». Но они сильно отличаются от компонентов «Битрикса», хотя мы старались максимально сохранить стандартный функционал.

Какое-то время мы поддерживали оба функционала — для «Битрикса» и «Эластика», на случай, если «Эластик» упадет. Из-за этого любое изменение в функционале новых компонентов влекло за собой двойную, а иногда и тройную работу. После того как мы убедились, что новая система работает корректно и без сбоев, мы решили не поддерживать компоненты «Битрикса».

Эффективность Elasticsearch

Какой же эффект дает использование Elasticsearch? Очень хороший – скорость загрузки страниц возрастает в несколько раз. Приведем несколько примеров роста производительности:

* значения указаны с учетом кэширования, без учета подгрузки javascript, картинок и т.д., без учета среднестатистических данных в период средней нагрузки на сайт
* значения указаны с учетом кэширования, без учета подгрузки javascript, картинок и т.д., без учета среднестатистических данных в период средней нагрузки на сайт

Похожего результата можно было бы добиться при грамотно настроенном кэшировании (у нас оно тоже настроено, на memcache), вынесением нужных свойств в отдельные таблицы и т.д. Но! Переиндексация, первые запросы на страницах работают без сформированного кэша. И в этих моментах производительность все равно сильно упадет. И недостатки работы с фасетными индексами тоже останутся. В общем, Kari такой вариант не подходит. Да и большинству крупных интернет-магазинов тоже.

С ростом количества посетителей сайт ощущает себя вполне комфортно. Пиковое значение онлайн-пользователей за одну секунду, которое нам удалось получить во время одной из рассылок — около 500 человек. И при этом сайт работал быстро.

Преимущества Еlasticsearch

Основная причина выбора Еlasticsearch — крутой поиск, который позволяет получать данные из индекса «за один запрос». Поиск осуществляется при помощи QueryDSL — языка построения запросов к Elasticsearch. Он сложный, требует практики и изучения тонн мануала. Но все это окупается результатами работы.

1. После добавления документа в индекс поиск по этому документу доступен уже менее чем через 1 секунду.

2. Структура хранения данных в Еlasticsearch произвольная, что позволяет хранить документы в удобном, подготовленном виде.

3. Мы используем Еlasticsearch еще и для хранения серверных логов. А выводим их в Kibana.

4. Ну и конечно, Еlasticsearch очень быстр! Запрос для одного раздела обрабатывается за 0,03 секунды.

5. Еще одна причина выбора Еlasticsearch — огромные возможности пользовательского поиска, которые мы, к сожалению, пока не используем в полной мере. На основе Еlasticsearch можно настроить отличный поиск по различным типам запросов, с применением анализаторов, поисковых алгоритмов и нечеткого поиска. Этот функционал мы планируем реализовать в ближайшее время.

Выводы

Хранение каталога товаров в Еlasticsearch решило поставленные перед нами задачи. Мы увеличили скорость работы сайта kari.com с учетом множества тяжелых импортов, экспортов и сложной внутренней логики.

Система передачи данных между «1С-Битрикс» и Еlasticsearch позволила более равномерно распределить нагрузку на серверы. Благодаря этому данные своевременно обновляются даже в пиковые нагрузки во время рассылок и наплыва посетителей.

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

В целом процесс внедрения Еlasticsearch оказался очень непростым. Несмотря на успешное решение задачи, осталась часть функционала, которая работает не так быстро, как хотелось бы. Например, логика «страна-город-склады-остатки-цены» работает по стандартной «битриксовой» схеме, которая работает довольно медленно при текущей нагрузке, что влияет на общую скорость сайта. Но эти проблемы мы постепенно решим с помощью нового функционала.

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

Для крупных проектов внедрение Еlasticsearch позволит существенно ускорить внутренние процессы и в целом весь сайт. Мы в Aero планируем перевести на Еlasticsearch товарные каталоги на всех наших проектах.

88
8 комментариев

Был удивлён увидеть такую техническую статью тут. А почему один инстанс используете , если это критичный участок? На самом деле кластер из коробки работает, правда для продакшена потребуется 2 сервера с оперативной памятью не менее 8gb. И парни, без обид - но то, что вы описали - это не высокие нагрузки. Высокие нагрузки, когда сотни тысяч в секунду соединений и десятки миллионов в сутки. Простите занудство :) Кстати, про elastic - там главное понять 2 вещи: то, что он работает поверх lucene , и маппинг. В остальном предлагаю не вводить в заблуждение людей. Это поисковый движок, с ним нельзя постоянно работать как с реляционной базой данных: создавать и удалять индексы, а также перезаписывать данные в привычной манере. Все ответы лежат в области lucene. Время поиска тоже настраивается, это у них по умолчанию стоит 30 сек. А так, он хорош! Вы тоже молодцы, что не боитесь тяжёлых задач. Успехов

3
Ответить

Александр, эти вещи нам понятны. Такая схема работает больше года, проблем никаких не замечено. Высокие нагрузки - понятие относительное. Высокая нагрузка может быть и на маленьком проекте, когда не хватает ресурсов простого сервачка. На этом проекте это немалые нагрузки, да и буквально на днях мы побили этот "рекорд". Раскрыть все цифры я к сожалению не могу, но если смотреть в разрезе до/после, сайт стал намного "выносливее", по сравнению с жизнью "до".

1
Ответить

Мы в своё время сделали то же самое для Mascotte. Разница в том, что мы выгружали все свойства товаров в ES, а это позволяет делать интересные вещи, как, например, подборку похожих товаров с разным весом для разных совпадающих параметров.

Что касается количества инстансов — сейчас уже многие облачные провайдеры предоставляют ElasticSearch в облаке — AWS, например. Но это скорее вопрос географии.

1
Ответить

Перепутали, Хабр в другой закладке?
А в целом крутаны и молодцы.

1
Ответить

Если кратко то: не используйте битрикс для больших сайтов (более 10к страниц) да?

Ответить

Не совсем так. Все зависит от конкретного проекта и конкретных задач. При создании магазинов мы используем битрикс. С большинством задач он справляется хорошо и имеет как плюсы, так и минусы. На сложных проектах нам приходится разрабатывать кастомные решения. На проектах попроще - более менее стандартный функционал. Ответ на ваш вопрос - нет, используйте битрикс, но не стоит упираться в его ограничения и минусы :)

2
Ответить