Знаете анекдот про самолет, в котором есть и бар, и бассейн, и ресторан, но только при взлете стюардесса говорит: «А теперь со всем этим мы попробуем взлететь»?

Веб-разработка немного похожа на такой самолет. Заказчик хочет от веб-студии и классный дизайн, и кучу интерактива, и все службы доставки и оплаты в интернет-магазины, студия с удовольствием все это программирует… А вот хватит ли мощностей сервера на обеспечение стабильной работы сайта — непонятно.
Чтобы нагрузка была прогнозируемой, чтобы задать некоторые эталонные значения, мы провели нагрузочное тестирование «1С-Битрикс: Управление сайтом» и «1С-Битрикс: Энтерпрайз».

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

В этой статье мы расскажем о том, как организовывали и проводили тестирование, и какие выводы для себя сделали.

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

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

Постановка задачи


Многие по разному понимают смысл, цель и задачи нагрузочного тестирования.

Для начала, нужно сформулировать для себя — чего же мы хотим?

Какой продукт и в каком виде тестировать?
Сначала мы хотели взять реально существующий интернет-магазин, его код и базу. Но это было бы тестирование именно этого решения, другие разработчики не смогут использовать его в качестве точки отсчета. Значит, тестировать надо стандартную «коробку», заполнив ее большим количеством позиций, соответствующим крупному интернет-магазину (по нашему опыту, это около 100 000 SKU). «1С-Битрикс» работал с включенной технологией «Композитного кэша» — решения, которое сначала подгружает быстрый кэш сохраненной страницы из nginx, а следом — ajax-запросом подгружает динамические данные. Таким образом, пользователь получает страницу максимально быстро. Для оценки числа запросов в секунду мы считали именно динамические запросы.

Какая должна быть серверная архитектура?
Обязательно надо протестировать односерверную конфигурацию: она самая простая и самая популярная. Но интересно также понять, насколько увеличится производительность, если добавить второй сервер? Вырастет ли она в два раза? Что будет, если использовать кластер из четырех машин? Можно ли успешно масштабировать горизонтально, добавляя новые и новые серверы в кластер?

Таким образом, было принято решение тестировать конфигурации из одного сервера, из двух и из четырех.

Какие нужно создать сценарии нагрузки?
По результатам анализа нагрузки на ряд крупных магазинов, трафик интернет-магазина можно разделить на 3 категории:

  1. 60% пользователей приходят и просматривают несколько страниц в каталоге, зная, какой конкретно товар им нужен.
  2. 37% пользователей выбирают нужный товар из нескольких возможных, применяют фильтрацию (smart-фильтр).
  3. 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 потоков

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

На этом этапе мы столкнулись с рядом сложностей. Из опыта их преодоления мы вынесли ряд уроков:

  1. Организуя нагрузочное тестирование, помните, что первый большой прогон теста будет далек от идеальных результатов. Возможно, вы что-то забудете в конфигурации ОС и софта сервера. Возможно, будут проблемы с самой системой тестирования (JMeter — это Java-приложение, со свойственными ему проблемами со сборкой мусора). Ну и главное — вы увидите тонкие места в своей системе, которые ранее не замечали и которые можно будет исправить. Например, в рамках нашего тестирования были обнаружены девять значимых багов, исправления которых выйдут в ближайших версиях продукта. Так что рассматривайте свой первый тест как инструкцию к оптимизации.
  2. Несколько очевидная вещь, которую однако стоит проговорить: во время оптимизации все изменения конфигурации на серверах должны фиксироваться. В идеале не применяйте больше, чем несколько изменений за раз. Иначе будет трудно выяснить, какое же именно действие привело к улучшению производительности.
  3. Суточное тестирование при наличии любой, не обнаруженной сразу ошибки — это потерянный день работы. После одной из итераций, когда мы внесли ряд изменений в конфигурацию, получили хорошие результаты и были тому обрадованы. Но потом обнаружили, что был отключен третий сценарий — оформление заказов пользователей, самый тяжелый в нашем случае. Пришлось запускать тестирование заново. Через сутки выяснили, что примененные изменения не ускоряют систему.
  4. Система под нагрузочным тестом — это продакшн-система, и с ней могут случится все те же типовые проблемы, которые происходят на продакшн-сайтах. У нас в одном из тестов, через 12 часов после запуска, на одном из серверов закончилось место. Поэтому жизненно необходимо поставить стандартные оповещения о проблемах на сайте в своей привычной системе мониторинга, чтобы они приходили вам на телефон. И при получении нужно немедленно бежать исправлять ситуацию, чтобы не потерять уже собранные драгоценные данные.
  5. Хорошие результаты чаще всего означают ошибки в тестировании. В одной из итераций мы получили двукратный прирост по сравнению с предыдущим тестом. Оказалось, что MySQL «вылетал» по max connections, а сайт в таких ситуация отвечал валидным для системы тестирования кодом HTTP 200.
  6. В любом тестировании очень важна «бюрократия»: делайте максимально подробное описание проведённого теста — сценарии, конфигурацию системы, логи тестирования и т.д. Все это будет полезно для последующего анализа.

Третий этап — сам тест. После того, как все процедуры отработаны, а система оптимизирована, лучше прогнать тест несколько раз. По нашему опыту, это позволяет получить действительно точный результат, который даже на 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. Что происходит с системой после достижения ее пределов в рамках одного сервера, что можно в ней оптимизировать?
  2. Как быстро система восстановится после сверхвысокой нагрузки?
  3. Как получить такой инструментарий, чтобы разработчики могли оценить реальное число пользователей, которое может обслужить созданный ими проект на текущем оборудовании?

Мы обязательно расскажем о результатах этого теста и вынесенном опыте.

Полезные ссылки:
  1. Подробный отчет о нагрузочном тестировании 1С-Битрикс
  2. Доклад Алексея Лавренюка о Яндекс.Танк в рамках конференции FailOver Conference 2015
  3. Тюнинг JMeter

Комментарии (29)


  1. bromzh
    08.07.2015 09:46

    Понятно, что тут тестируется уже готовое приложение, но интересно было бы увидеть результаты в сравнении с другими решениями, например на JavaEE. Базу взять одну, и написать к ней простые магазины с одинаковой логикой, понагружать это всё и сравнить между собой.


    1. SerafimArts
      08.07.2015 12:12

      Ну с Java примеры не приведу, но вот например популярные фреймы: github.com/kenjis/php-framework-benchmark


    1. DarthVictor
      08.07.2015 12:17

      По-моему это мало реально, на том же benchmarksgame.alioth.debian.org сравнение получается не очень корректным из-за немного разных реализация. При том что там довольно простые числодробильные алгоритмы, без взаимодействия с базой, сетью, без сложного многопроцессного взаимодействия. И все равно разные реализации одного алгоритма на одном языке там имеют результат, отличающийся раз в пять. Чем сложнее задача, тем больше будет узких мест, которые больше зависят от правильности реализации конкретной библиотеки или слоя приложения.
      Для серверных систем самое объемное тестирование, попадавшееся мне, это www.techempower.com/benchmarks/#section=data-r10
      В нем еще грамотно подходят, деля системы по принципу платформа/микрофреймворк/фреймворк.


      1. bromzh
        08.07.2015 14:37

        Ну понятно, что тут интерес не в том, чтобы сравнивать Java и php как языки. Про вторую ссылку я знаю и хотелось бы сравнения именно в таком ключе.


        1. nryzhonin
          08.07.2015 15:04

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


  1. murzix
    08.07.2015 13:07
    +1

    А конфигом тестовой БД не поделитесь?


    1. naoise
      08.07.2015 13:31

      привет! я из ITSumma,
      вот здесь собраны все все конфиги
      itsumma.ru/1c-bitrix-test/enterprise_test_config.zip


      1. murzix
        08.07.2015 13:46

        Спасибо =) Будем изучать.


      1. murzix
        09.07.2015 17:26

        В вашем конфиге key_buffer = 128M

        Это корректное значение? В базе нет myisam таблиц? Почему не key_buffer_size?


        1. nryzhonin
          04.08.2015 15:38

          Временные таблицы в mysql в формате MyISAM


  1. sunnybear
    08.07.2015 14:39

    phantomjs позволяет использовать POST и cookie. Мы его так уже 3,5 года используем.


    1. naoise
      08.07.2015 14:54

      тут видимо мы не до конца ясно выразились — речь именно о модуле Phantom — не PhantomJS
      github.com/yandex/yandex-tank/wiki/%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C-Phantom


      1. sunnybear
        08.07.2015 15:19
        +1

        да, прошу прощения, phantom — это совершенно другая либа, github.com/mamchits/phantom


  1. DmitryKoterov
    08.07.2015 15:41
    +1

    Поясните, пожалуйста, что за запросы составляют «0.3% невыполненных запросов»? Понятно, что в продакшене такой процент всегда существует — ведь пользовательское поведение непредсказуемо вариативно. Но в тестовой-то среде, при нагрузочном тестировании, вариативность очень низка. Откуда бы взяться проценту ошибок? Если это баги, то их нагрузочный тест выявляет конечное количество, и после их исправлени данный конкретный нагрузочный тест должен порождать 0% отказов.


    1. nryzhonin
      08.07.2015 15:56

      Различные сетевые ошибки. Нагрузка в тесте была максимальной, на пределе возможностей железа, отсюда и возникновение различных сбойных хитов.

      Что касается программной части, то на тестах не было ошибок php, mysql, apache, nginx.


      1. DmitryKoterov
        08.07.2015 23:42
        +1

        Что-то много как-то этих «сетевых ошибок». Для TCP-стека 1000 коннектов в секунду — сущая безделица. Было бы все же очень интересно узнать поподробнее в статье, что это были за ошибки. Вот в то, что таймаутились запросы к базе или PHP вылетал по max_execution_time (по причине высокой загрузки дисков), это было бы более похоже на правду.


        1. nryzhonin
          10.07.2015 15:40

          Ошибок php или БД в тесте не было. Часть сетевых ошибок происходило на уровне java — Jmeter


  1. neonox
    08.07.2015 15:53

    naoise, немного не по теме, но тоже в отношении 1С Битрикс.
    Корпоративный портал выдает очень мало попугаев выдает — 10-13.
    Пробовал разные конфиги (Ваш последний не пробовал), пробовал переходить на Percona, попугаи подтянулись до 20, но сам корпоративный портал все равно работает медленно.
    Может у вас best practice в этом моменте?


    1. nryzhonin
      08.07.2015 16:00

      1. Многое зависит от железа
      2. Учли все замечания модуля производительности
      3. Есть ли сторонние модули?


      1. neonox
        08.07.2015 16:37

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


        1. nryzhonin
          08.07.2015 17:08

          Скорость работы сильно зависит от диска. Модули xdebug, xhprof отключены? Какой прекомпилятор используется?


    1. piroman
      08.07.2015 21:56
      +1

      Насоветуют вам сейчас всяческие «специалисты» железо, сас контролеру и прочую темную хрень.

      30 попугаев в битриксе можно получить на любом акутальном железе (ну, может, кроме атома)
      1) Лезем в панель производительности. Почти все рекомендации там уже есть.
      2) Лезем в раздел БД, подкручиваем my.cnf
      3) Выносим /tmp в память, ибо высокий профессионализм разработчиков битрикса не позволяет им обходиться без временных таблиц. Тут, конечно, можно насиловать диск, SSD или писать временные таблицы в кеш контроллера с батарейкой за 2000$, но лучше в память. Дешевле и быстрее.

      (Что до статьи, то сильно рассмешили люди, тестирующие что то на неактуальном софте. Centos 6 обсолейт уже год, простите. Мозгов на актуальный диструбутив не хватило?)


      1. piroman
        08.07.2015 22:03

        Забыл, Zend opcache маст. Всякие APC и прочие Xcache рядом не стояли.


      1. nryzhonin
        09.07.2015 01:31

        CentOS 6.Х выбрана в качестве основы, с целью использования готового окружения BitrixEnv. Это позволяет сразу получить оптимально настроенное окружение.


  1. sply
    08.07.2015 18:55
    +2

    Очень хорошо организован и описан процесс, респект.

    Можете поделиться заданиями для скриптов тестирования и дампом тестового сайта? Мы сейчас собираемся прогнать нормальные нагрузочные тесты Битрикса на нашей платформе, и было бы интересно сравнить на одинаковой задаче. Особенно интересно оценить работу композитного кэша.


    1. naoise
      09.07.2015 15:58
      +1

      1. sply
        09.07.2015 17:07

        Спасибо, а дампа тестового сайта нет?


        1. naoise
          09.07.2015 19:07

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


          1. sply
            10.07.2015 00:18

            Это будет вообще отлично!