Концепция производительности и масштабируемости Spryker

в 17:05, , рубрики: e-commerce, performance, performance tests, php, высокая производительность, Разработка под e-commerce

Предлагаю вашему вниманию перевод статьи Spryker Performance and Scalability Concepts.

Spryker это e‑commerce фреймворк, является результатом реализации более чем 100 индивидуальных e‑commerce проектов. Он предоставляет из коробки два важнейших архитектурных качества — высокую производительность и масштабируемость. В этой статье описываются основные концепции для их достижения.

Почему производительность и маштабируемость так важны?

Всем известно, что низкая производительность сервера — настоящий убийца конверсии. Без сомнения, быстрый вебсайт – приятен в использовании, но есть и другие причины бороться за уменьшение времени отклика сервера.

Возможно, вы помните сложности работы с медленным приложением при высокой нагрузке. В Spryker мы хотим быть уверенными, что онлайн магазин никогда не станет “узким местом” при любой маркетинговой кампании, будь то TV реклама, массовая рассылка или SEM-кампании.

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

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

Архитектурные цели

При нормальной нагрузке, типичный Spryker-Магазин должен иметь среднее время отклика около 50 мс. Даже такие затратные запросы, такие как добавление товара в корзину, должны выполняться менее чем за 150 мс. Если эти цифры вам ни о чем не говорят, можно сравнить их с (неофициальными) тестами производительности Magento, которые были опубликованы Дмитрием Сорокой. Дмитрий — бывший лид-архитектор Magento, так что можно предположить, что его цифры не сильно отличаются от действительности. Он сравнивал старую, но все еще известную, Magento 1 с новой Magento 2:

На странице продукта Magento 1 отклик сервера составлял 250 мс или менее в 90% случаев. Для Magento 2, менее чем 25% запросов смогли уложиться в 250 мс. Как показано на графике ниже, большинство запросов выполнялись 600 мс и более.

В сравнении с этими результатами, Spryker в 5 раз быстрее чем Magento 1 и 5-12 раз быстрее Magento 2. В качестве первого ознакомления с нашими результатами мы ниже приводим график времени отклика домашней страницы Spryker-магазина (ее поведение похоже на страницу продукта). Тестирование проводилось на одном сервере Heroku при нагрузке в 3000 запросов в минуту, какое-либо полностраничное кеширование отсутствует.

image
3k RPM / Heroku 1 Performance L Dyno / PHP7

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

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

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

Оптимизированный дизайн программного обеспечения

Для достижения вышеперечисленных целей, мы решили разделить приложение магазина на две части: Yves и Zed. Yves — клиентский front-end. Это небольшое PHP приложение основанное на микрофреймверке Silex от SensioLabs. Zed — “тяжелое” серверное приложение, содержащее всю бизнес-логику.

Yves обеспечивает бóльшую часть своей скорости за счет упрощенного дизайна без лишних архитектурных слоев и облегченном процессе загрузки. Другой важный концепт Yves — это способ доступа к данным. Вместо затратных SQL-запросов к реляционной базе данных с множеством связей и условий, Yves считывает данные из очень быстрого хранилища данных типа «ключ — значение» (по умолчанию это Redis). Быстрота полнотекстового и фасетного поиска для Yves обязана мощному Elasticsearch. Реляционная база данных, которая часто становится узким местом для масштабируемости, недоступна напрямую из Yves. Вместо этого, Zed собирает все изменения данных и помещает их в подготовленном виде в Redis и Elasticsearch.

image

Производительность Yves

Чтобы оценить производительность Yves, рассмотрим последовательность его действий. Типичный запрос Yves выглядит следующим образом:

(1) Парсинг URL
(2) Получение всех данных из Redis и/или Elasticsearch
(3) Добавление этих данных в предварительно скомпилированные шаблоны Twig

Очевидно, тут не так много действий для PHP кода, быстрой из-за упрощенной архитектуры. С точки зрения производительности, наиболее критичная часть начинается на втором шаге, когда Yves получает данные из Redis и/или Elasticsearch. Все данные о продуктах, CMS страницах и переводах хранятся в Redis. С другой стороны, нормализованной реляционной базе данных PostgreSQL или MySQL информация о каждом продукте распределяется между несколькими таблицами: акции, цены, налоги и т.д.; все это гидрируется в единый набор данных, который хранится в Redis. Вместо нескольких затратных запросов, Yves просто выполняет Redis::get(), для получения всех необходимых данных сразу.

Каждая страница требует несколько наборов данных. Redis очень быстр, даже с большими объемами данных и большим числом подключений. В случае установки Redis на одном сервере со Spryker, один запрос Redis::get() занимает всего 0,1 мс. В случае, если вы запускаете Spryker в облачном сервисе, что делает 90% наших клиентов, проявляется сетевая задержка. Вместо быстрого поиска в оперативной памяти для локального Redis, медленная сеть значительно увеличивает время выполнения. По этой причине, Yves автоматически объединяет данные в единый запрос Redis::mget() вместо десятков Redis::get(). Это позволяет нивелировать концептуальные ограничения облачных сервисов и получить максимальную производительность от Redis.

В отличие от Redis, Elasticsearch используется только для каталога. Мы выполняем только один запрос, но этот запрос гораздо медленнее, чем Redis::get(). Для предотвращения медленных запросов мы оптимизировали заполнение индекса, при котором данные подготовлены для быстрого поиска. Мы расскажем об этом подробно в другой статье.

И, наконец, я хотел бы сказать несколько слов о масштабируемости. Для подготовки Spryker к масштабируемости в облачных сервисах, мы строго соблюдаем методологию двенадцати факторов. Наиболее важной её частью является то, что «процессы приложения не хранят своё внутреннее состояние (stateless) и не имеют разделяемых данных (share-nothing)». Все части Yves можно масштабировать независимо от других частей приложения. Вы можете добавить больше экземпляров Yves, или дополнительные ресурсы для Redis или Elasticsearch. Все это возможно без простоев, вам даже не нужно развертывать приложение. Подробнее этот вопрос будет освящен в будущих статьях

Мы будем рады, если вы ознакомитесь с проектом Spryker. Он с легкостью запустится на вашем компьютере, так как все настройки подготовлены в базовой виртуальной машине для VirtualBox. Важно: Opcache отключен в данном образе.

Автор: ipartemk

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js