Нагрузочное тестирование CMS «1С-Битрикс»
Знаете анекдот про самолет, в котором есть и бар, и бассейн, и ресторан, но только при взлете стюардесса говорит: «А теперь со всем этим мы попробуем взлететь»?
Веб-разработка немного похожа на такой самолет. Заказчик хочет от веб-студии и классный дизайн, и кучу интерактива, и все службы доставки и оплаты в интернет-магазины, студия с удовольствием все это программирует… А вот хватит ли мощностей сервера на обеспечение стабильной работы сайта — непонятно.
Чтобы нагрузка была прогнозируемой, чтобы задать некоторые эталонные значения, мы провели нагрузочное тестирование »1С-Битрикс: Управление сайтом» и »1С-Битрикс: Энтерпрайз».
Мы постарались так провести тестирование, чтобы клиент понимал, что можно получить на текущем оборудовании, а разработчик мог понять, каковы перспективы роста проекта. Получится ли отмасштабироваться при росте нагрузки?
В этой статье мы расскажем о том, как организовывали и проводили тестирование, и какие выводы для себя сделали.
Для чего это может быть полезно? Эталонные цифры дадут возможность сравнить текущую площадку с потенциальным новым хостингом, четко оценить, какой эффект оказывает на систему внедрение новой функциональности. Да и просто понять технические пределы системы.
Мы сделали акцент на вопросах организации тестирования, на специфических проблемах, с которыми столкнулись в процессе тестирования и на том, какие выводы можно сделать по результатам тестов. Для самых заинтересованных — вот ссылка на подробный технический отчет.
Постановка задачи
Многие по разному понимают смысл, цель и задачи нагрузочного тестирования.
Для начала, нужно сформулировать для себя — чего же мы хотим?
Какой продукт и в каком виде тестировать?
Сначала мы хотели взять реально существующий интернет-магазин, его код и базу. Но это было бы тестирование именно этого решения, другие разработчики не смогут использовать его в качестве точки отсчета. Значит, тестировать надо стандартную «коробку», заполнив ее большим количеством позиций, соответствующим крупному интернет-магазину (по нашему опыту, это около 100 000 SKU).»1С-Битрикс» работал с включенной технологией «Композитного кэша» — решения, которое сначала подгружает быстрый кэш сохраненной страницы из nginx, а следом — ajax-запросом подгружает динамические данные. Таким образом, пользователь получает страницу максимально быстро. Для оценки числа запросов в секунду мы считали именно динамические запросы.
Какая должна быть серверная архитектура?
Обязательно надо протестировать односерверную конфигурацию: она самая простая и самая популярная. Но интересно также понять, насколько увеличится производительность, если добавить второй сервер? Вырастет ли она в два раза? Что будет, если использовать кластер из четырех машин? Можно ли успешно масштабировать горизонтально, добавляя новые и новые серверы в кластер?
Таким образом, было принято решение тестировать конфигурации из одного сервера, из двух и из четырех.
Какие нужно создать сценарии нагрузки?
По результатам анализа нагрузки на ряд крупных магазинов, трафик интернет-магазина можно разделить на 3 категории:
- 60% пользователей приходят и просматривают несколько страниц в каталоге, зная, какой конкретно товар им нужен.
- 37% пользователей выбирают нужный товар из нескольких возможных, применяют фильтрацию (smart-фильтр).
- 3% пользователей (стандартный показатель хорошей конверсии) положили товар в корзину и купили его.
Как именно нагружать серверы?
Существует две основных модели нагрузочного тестирования проекта: закрытая и открытая. Закрытая подразумевает собой искусственную постоянную статичную нагрузку, в которой запросы «пользователей» идут статичным потоком (а не волнами, как в реальной жизни). Ее цель — выяснить поведение проекта при максимуме нагрузки, понять максимальную «пропускную способность» системы. Это верхняя планка метрики, выше нее уже не подняться.
Открытая модель подразумевает тестирование, близкое к реальной жизни: пользователи приходят волнами, иногда большими, чем может выдержать система. Это помогает выяснить пределы работы системы, как она поведет себя в критических условиях.
В данном тесте нашей целью было выяснить пропускную способность системы, поэтому мы выбрали закрытую модель при той максимальной нагрузке, на которой будет выдержан SLA.
Какой SLA выбрать для тестирования?
Нам нужно было четко обозначить для себя тот порог, ниже которого мы считаем систему стабильно обслуживающей запросы. Для этого мы воспользовались статистикой ТОП-100 крупных интернет-магазинов (по версии издания «Коммерсант», 2014 г.) и выбрали две главные метрики: ответ на 99% запросов должен быть дан меньше чем за 1 секунду, а число ответов с кодом, отличным от HTTP 200, должно быть не более 0,5%. Тестирование должно вестись непрерывно в течение 24 часов.
Какой хостинг выбрать?
В качестве площадки для тестирования мы выбрали хостинг Selectel с дата-центром «Цветочная-1» в Санкт-Петербурге. Selectel предоставил нам серверы самой популярной своей конфигурации — Intel Xeon E3–1270v3 3,5 ГГц, 32 Гб оперативной памяти, 2 × 240 Гб SSD-накопители в RAID 1. Один из серверов был использован как центр нагрузки, остальные, в разных конфигурациях »1С-Битрикс», мы использовали для тестирования.
Конфигурация системы
В рамках тестирования серверы работали на ОС Linux CentOS 6.6 с установленным на нем пакетом »1С-Битрикс: Веб-окружение», подробнее о нем можно почитать здесь.
PHP в системе был обновлен до версии 5.6.9, а директории кэшей были смонтированы в tmpfs. Для тестирования были подготовлены три конфигурации:
1) 1 сервер.»1С-Битрикс: Управление сайтом», web и MySQL работают на одном сервере
2) 2 сервера.»1С-Битрикс: Энтерпрайз», балансировщик nginx на первом сервере, web-application на обоих серверах, MySQL мастер и запись/чтение в него — на первом сервере, MySQL slave и чтение из него — на втором сервере
3) четыре сервера. Вариант, в котором вторая конфигурация горизонтально отмасштабирована slave-машиной.
Чем тестировать?
В качестве средства тестирования был выбран Яндекс.Танк. Яндекс.Танк позволяет использовать две системы генерации нагрузки — Phantom и JMeter. Phantom превосходит JMeter в плане производительности, однако не позволяет генерировать POST-логику, сохранение и последующее использование куков. По этой причине мы генерировали нагрузку с помощью JMeter.
Кто тестирует?
Нам хотелось, чтобы тестирование провела независимая компания, мнению которой могли бы доверять и мы, и сторонние компании, и эксперты индустрии. Это задачу мы доверили компании ITSumma, которая с 2008 года занимается круглосуточным администрированием и технической поддержкой известных в Рунете проектов и зарекомендовала себя на рынке. Ее сотрудники являются постоянными докладчиками профильных конференций (таких как Highload, РИТ++ и др.).
Тестирование
В ретроспективе тестирование можно разбить на три этапа.
Первый этап — примерочная стрельба, в рамках которой мы подбирали максимальное число потоков, при котором будет сохраняться SLA:
- односерверная конфигурация: 34 потока
- конфигурация из двух серверов: 74 потока
- конфигурация из четырех серверов: 136 потоков
Второй этап — первые попытки запустить полноценный тест. Планируя нагрузочное тестирование, нужно понимать, что определенное время займет как доработка системы, на которой будет производиться тест, так и отработка самой процедуры теста.
На этом этапе мы столкнулись с рядом сложностей. Из опыта их преодоления мы вынесли ряд уроков:
- Организуя нагрузочное тестирование, помните, что первый большой прогон теста будет далек от идеальных результатов. Возможно, вы что-то забудете в конфигурации ОС и софта сервера. Возможно, будут проблемы с самой системой тестирования (JMeter — это Java-приложение, со свойственными ему проблемами со сборкой мусора). Ну и главное — вы увидите тонкие места в своей системе, которые ранее не замечали и которые можно будет исправить. Например, в рамках нашего тестирования были обнаружены девять значимых багов, исправления которых выйдут в ближайших версиях продукта. Так что рассматривайте свой первый тест как инструкцию к оптимизации.
- Несколько очевидная вещь, которую однако стоит проговорить: во время оптимизации все изменения конфигурации на серверах должны фиксироваться. В идеале не применяйте больше, чем несколько изменений за раз. Иначе будет трудно выяснить, какое же именно действие привело к улучшению производительности.
- Суточное тестирование при наличии любой, не обнаруженной сразу ошибки — это потерянный день работы. После одной из итераций, когда мы внесли ряд изменений в конфигурацию, получили хорошие результаты и были тому обрадованы. Но потом обнаружили, что был отключен третий сценарий — оформление заказов пользователей, самый тяжелый в нашем случае. Пришлось запускать тестирование заново. Через сутки выяснили, что примененные изменения не ускоряют систему.
- Система под нагрузочным тестом — это продакшн-система, и с ней могут случится все те же типовые проблемы, которые происходят на продакшн-сайтах. У нас в одном из тестов, через 12 часов после запуска, на одном из серверов закончилось место. Поэтому жизненно необходимо поставить стандартные оповещения о проблемах на сайте в своей привычной системе мониторинга, чтобы они приходили вам на телефон. И при получении нужно немедленно бежать исправлять ситуацию, чтобы не потерять уже собранные драгоценные данные.
- Хорошие результаты чаще всего означают ошибки в тестировании. В одной из итераций мы получили двукратный прирост по сравнению с предыдущим тестом. Оказалось, что MySQL «вылетал» по max connections, а сайт в таких ситуация отвечал валидным для системы тестирования кодом HTTP 200.
- В любом тестировании очень важна «бюрократия»: делайте максимально подробное описание проведённого теста — сценарии, конфигурацию системы, логи тестирования и т.д. Все это будет полезно для последующего анализа.
Третий этап — сам тест. После того, как все процедуры отработаны, а система оптимизирована, лучше прогнать тест несколько раз. По нашему опыту, это позволяет получить действительно точный результат, который даже на 24-х часовом тестировании будет практически идентичен такому же тесту. В повторах своих тестов мы получали результаты с точностью до запросов в секунду.
Результаты тестирования
Конфигурация 1 (1 сервер,»1С-Битрикс: Управление Сайтом», редакция «Бизнес»)
Время выполнения теста: 86 892 секунды
- Число PHP-запросов в секунду: 167, при 34 одновременных потоках
- 99-процентиль: 0,366 мс.
- Число просмотренных страниц: 14 421 563
- Процент невыполненных запросов: 0,31%
Процентиль Яндекс.Танка
«Полка» RPS (верхняя граница — 350 запросов в секунду, включая «композитные» запросы — 167 динамических запросов в секунду).
Это хороший результат для сложной системы, при этом важно отметить, что основную нагрузку создают именно сложные процедуры добавления товара в корзину и его оформления.
Конфигурация 2 (2 сервера,»1С-Битрикс: Энтерпрайз»)
- Время выполнения теста: 86 850 секунд
- Число PHP-запросов в секунду: 265, при 74 одновременных потоках
- 99-процентиль: 0,95
- Число просмотренных страниц 23 082 301
- Процент невыполненных запросов: 0,47%
- Коэффициент масштабирования по сравнению с конфигурацией 1: 1,60
Процентиль Яндекс.Танка
«Полка» RPS (включая «композитные» запросы — верхняя граница — 550 запросов в секунду).
Число запросов в секунду выросло не так сильно, как хотелось бы — в 1,6 раз. Важно помнить, что в многосерверной конфигурации добавляется межсерверное взаимодействие и дополнительный overhead на обмен данными.
Конфигурация 3 (4 сервера,»1С-Битрикс: Энтерпрайз»)
- Время выполнения теста: 86 402 секунд
- Число PHP-запросов в секунду: 535, при 136 одновременных потоках
- 99-процентиль: 0,9
- Число просмотренных страниц: 46 256 141
- Процент невыполненных запросов: 0,47%
- Коэффициент масштабирования по сравнению с конфигурацией 2 — 2,00
Процентиль Яндекс.Танка
«Полка» RPS (включая «композитные» запросы — верхняя граница — 1100 запросов в секунду).
А вот здесь — отличный результат по масштабированию. Добавив еще два сервера к двухсерверной конфигурации, мы получили двукратный же прирост в производительности. Этот результат говорит о том, что вы не упретесь в вертикальные пределы «железа», дополнительные серверы позволят адекватно распределить нагрузку между машинами.
Итоги и дальнейшие планы
Этим тестированием мы старались задать некий эталон, на который могут ориентироваться разработчики при оценке производительности своих систем. Для нас очень важным результатом стало подтверждение высокой эффективности горизонтального масштабирования »1С-Битрикс»: использование четырех серверов вместо двух и дало двукратный прирост. Ну и, конечно, приятная метрика — 167 запросов на динамике в сложной системе на одном сервере.
Теперь мы планируем провести тест уже в открытой системе, чтобы выяснить для себя следующие моменты:
- Что происходит с системой после достижения ее пределов в рамках одного сервера, что можно в ней оптимизировать?
- Как быстро система восстановится после сверхвысокой нагрузки?
- Как получить такой инструментарий, чтобы разработчики могли оценить реальное число пользователей, которое может обслужить созданный ими проект на текущем оборудовании?
Мы обязательно расскажем о результатах этого теста и вынесенном опыте.
Полезные ссылки:
- Подробный отчет о нагрузочном тестировании 1С-Битрикс
- Доклад Алексея Лавренюка о Яндекс.Танк в рамках конференции FailOver Conference 2015
- Тюнинг JMeter