Результаты нагрузочного тестирования. Кому удавалось получить более 200+ одновременных соединений?

Главные вкладки

Аватар пользователя arsen.borovinskiy arsen.borovinskiy 26 декабря 2014 в 3:47

Провел нагрузочное тестирование.

Конфигурация:

1) 1 сервер БД MySQL 5.1, 16 vCPU/3GHz, 18 GB RAM, 12 GB под InnoDB, 10GB Ethernet.
2) 1 сервер под кеш Redis или Memcache c выделенными 4GB, 10GB Ethernet.
3) 3 сервера nginx/php-fpm, drupal7, 16 vCPU/3GHz, 8GB RAM, APC, HDD примерно 400 IOPS, 10GB Ethernet.
4) 1 балансировщик nginx 4vCPU, без кеширования ответов, 10GB Ethernet.

Все кеши Drupal в Redis, сессии в Redis. Пробовал вместо Redis использовать Memcache, разницы не заметил. Все таблицы MySQL в InnoDB.

В силу специфики сайта, Boost или кеширование для анонимов на балансировщике не использовалось.

Тестировал ab на различные ноды и JMeter по логам апача.

Результаты ab:

До 200 одновременных соединений Drupal держит, после чего начинают появляться 500 ошибки. При 400 одновременных соединений Drupal полностью не работает.

Результаты JMeter:

До 100 новых соединений в секунду Drupal держит. При 150 новых соединений в секунду Drupal сильно плохо. При 180-200 сайт падает.

На сервере БД MySQL нагрузка на файловую систему 15 IOPS, т.е. все данные берутся из кеша InnoDB или файлового кеша и в файловую систему производительность не упирается.
Если в JMeter добавить куку авторизованного пользователя, результаты ухудшаются примерно в 2 раза.
Файловые дескрипторы, tcp-стек, MySQL и т.п. - протюнинговано. Ошибок со стороны линукса или сервера нет. Память на серверах приложений не заканчивается.

Все 500 ошибки с руганью на MySQL.

Вопрос:

Кто до какой скорости разгонял Drupal при условии отсутствия кеширования страниц целиком для анонимов (Boost, кеш веб-сервера)?

Я что-то недонастроил или дошел до пиковой производительности Drupal? Как можно повысить производительность кроме кеширования страниц целиком?

Когда кеш прогрет, увеличение числа серверов приложений не дает роста производительности. Т.е. БД MySQL дай бог на 30% нагружена (ни одно ядро не нагружено на 100%) и сервера приложений тоже по 40%, но время генерации страницы не уменьшается. Т.е. сайт перестает масштабироваться горизонтально (добавление серверов приложений ничего не дает) и, по ходу, не масштабируется вертикально по БД (ядра MySQL нагружены всего на 30%).

Пробовал часть полей и сессии уносить в MongoDB - cущественной разницы не заметил.

Подозрение:

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

Кто что думает?

Комментарии

Аватар пользователя marazmus marazmus 26 декабря 2014 в 7:30

Осмелюсь предложить проверить для начала ту же нагрузку на MariaDB, и на PostgreSQL (на последнем кемпе был доклад на эту тему, кстати, то есть под подстгресом можно вполне жить, и он быстрее мускула на жирных проектах), и посмотреть что получится.

Аватар пользователя arsen.borovinskiy arsen.borovinskiy 29 декабря 2014 в 0:05

Поставил postgresql 9.4.

Ситуация с неполной нагрузкой не повторяется. Все ядра на серверах приложений и БД полностью утилизированны. Это уже хорошо. Выделил под кеши postgresql 4 GB. IOPS на диск БД во время теста нет, т.е. все берется из кеша.

Ошибка в таблице semaphore
При больших нагрузках в БД начала вылазить ошибка добавления существующего уникального ключа в таблицу semaphore. Для MySQL есть рекомендация конвертировать таблицу Semaphore в Memory, на крайний случай использовать MyISAM вместо InnoDB.

Для postgresql решение есть здесь: https://www.drupal.org/node/1650930#comment-8437127 только для postgresql установка уровня изоляции будет такой:

<?php
$databases
['default']['default']['init_commands'] = array(
  
'isolation' => "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED"
);
?>

Общире результаты сообщу несколько позднее.

Аватар пользователя marazmus marazmus 29 декабря 2014 в 7:20

"arsen.borovinskiy" wrote:
Все ядра на серверах приложений и БД полностью утилизированны

Это на скольки соединениях? Smile

"arsen.borovinskiy" wrote:
Общире результаты сообщу несколько позднее.

Держим пальцы крестиком, на друпал.ру редкий представитель инженерного мышления, ждем Smile

Аватар пользователя arsen.borovinskiy arsen.borovinskiy 11 января 2015 в 22:30

Нашел у себя ошибки в конфигурации. В тесте ApacheBench удалось уйти за 1000 конкурентных подключений без ошибок.

При этом я поменял тестовый стенд и провел "синтетическое" тестирование ApacheBench с разным количеством нод чтобы получить какие-то опорные данные для сайзинга серверов и сравнить MariaDB vs PostgreSQL.

С методикой тестирования, результатами и интерпретацией результатов предлагаю ознакомиться здесь: http://arsen-borovinskiy.blogspot.ru/2015/01/drupal-performance-benchmar...

В форуме лишь приведу пару картинок:

drupal postgresql performance benchmark result

drupal mysql mariadb performance benchmark result

Особо отмечу: это синтетический тест, оценивающий максимальную производительность от системы инициализации и вывода статического текста самописным модулем. При такой конфигурации MariaDB быстрее PostgreSQL.

Теперь почему у меня возникли проблемы с 200-400 конкурентными подключениями:
1) надо тюнить backlog, причем не только системный (sysctl), но и в php-fpm и в nginx,
2) php-fpm к nginx надо цеплять через tcp/ip, а не "более быстрые" сокеты.

Аватар пользователя borovinskiy borovinskiy 5 мая 2015 в 23:37

Вторая часть тестов, в которой из 1 млн. нод случайным образом выводится одна.

В этом тесте победу одержал PostgreSQL.

Методику и подробные результаты смотрите здесь:

http://arsen-borovinskiy.blogspot.ru/2015/05/drupal-mysql-vs-postgresql-...

Аватар пользователя bsyomov bsyomov 6 мая 2015 в 9:15

"arsen.borovinskiy" wrote:
php-fpm к nginx надо цеплять через tcp/ip, а не "более быстрые" сокеты.

В случае сокетов надо было обратить внимание на net.core.somaxconn, и лимит на открытые файлы для php-fpm

Аватар пользователя borovinskiy borovinskiy 6 мая 2015 в 11:59
net.core.somaxconn = 20000
fs.file-max=262144

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

Аватар пользователя bsyomov bsyomov 6 мая 2015 в 20:38

Тогда вопрос - а в какой именно таймаут вы упираетесь на unix socket и не упираетесь на ip socket?
Fastcgi read|send|connect определяется настройками nginx и не зависят от типа сокета. На стороне самого php-fpm тоже проблем быть не должно - там и находится источник задержки.

Аватар пользователя bsyomov bsyomov 10 мая 2015 в 13:06

"borovinskiy" wrote:
Рекомендация уехать на ip была на форуме nginx.

Вообще эта рекомендация в стиле "так проще чем разобраться". Smile
У меня работали проекты с 300+ rps, и соответственно, довольно большой конкурентностью запросов на unix сокетах, так что это не какая-то глобальная не решаемая проблема.

Аватар пользователя borovinskiy borovinskiy 13 мая 2015 в 0:39

Наверное вы правы и можно было еще повоевать, но в nginx не так много настроек с таймингами, а гугл другими решениями не помог. Собственно, вы и сами можете проверить свои сайты -), а то, может, у вас сервера помощнее или кеширование включено и свой лимит в каких-нибудь 600 rps вы еще не достигли.

В защиту ip могу сказать, что если вы уперлись в БД, то всякие микрооптимизации в виде сокетов существенно на время генерации страницы не повлияют. Тесты я в принципе начал проводить из-за довольно очевидного соображения, что если на вывод стандартной страницы Drupal генерирует 50 SQL-запросов, то при 1000 rps на сайте мы получаем 50 000 rps в БД, что явно много для среднестатистического сервера и является очевидным ограничением на масштабирование Drupal. Конечно, можно часть полей вынести в NoSQL, но тут повлияет необходимость каждый раз по сети поднимать соединение, что добавляет задержку, а что NoSQL будет прям сильно быстрее реляционок - вообще не факт.

В Drupal 8, вроде, переходят на текстовые конфиги. Просветите, кто знает подробнее -). Возможно это связано в том числе с ограниченной масштабируемостью Drupal из-за БД, а загрузка конфигурации из файла уменьшает число запросов в БД и легко горизонтально масштабируется.

Аватар пользователя Виктор Степаньков ака RxB Виктор Степаньк... 13 мая 2015 в 0:48

"borovinskiy" wrote:
В Drupal 8, вроде, переходят на текстовые конфиги. Просветите, кто знает подробнее -). Возможно это связано в том числе с ограниченной масштабируемостью Drupal из-за БД, а загрузка конфигурации из файла уменьшает число запросов в БД и легко горизонтально масштабируется.

переходят, в первую очередь, для упрощения деплоя