Нагрузочное тестирование БД перед запуском: SQLIO и JMeter находят узкое место
Перед запуском ERP на 200 пользователей прогоняем SQLIO на дисках и JMeter на приложении. Диски не тянут - добавляем RAID-контроллер с кешем.
Apache JMeter 2.x и Microsoft SQLIO получают распространение как инструменты нагрузочного тестирования баз данных и приложений
Клиент - дистрибьюторская компания, около двухсот пользователей - запускал новую ERP-систему. Проект шёл несколько месяцев, оставалась последняя неделя перед переключением на боевой режим. Нас попросили провести нагрузочное тестирование: убедиться, что система выдержит реальный рабочий день, а не стресс тестировщиков из расчёта «ну, наверное, потянет».
Мы с такой просьбой встречались не первый раз. Как правило, за ней стоит здоровое беспокойство: серьёзные деньги потрачены, переезд с кучей данных уже позади, возврата нет - хочется хоть какую-то гарантию. Гарантий мы не даём, но картину до запуска нарисовать можем.
Два инструмента, два уровня
Нагрузку решили мерить на двух уровнях: дисковая подсистема сервера БД отдельно, приложение целиком - отдельно.
SQLIO от Microsoft - утилита командной строки, имитирует случайные и последовательные операции чтения/записи на диск. Никакой базы данных, никакого SQL - просто чистый I/O. Выдаёт IOPS и throughput для заданного размера блока и глубины очереди. Именно так работает SQL Server внутри: чтение страниц по 8 КБ, запись в журнал блоками побольше.
Apache JMeter 2.x берёт на себя верхний уровень: HTTP-сессии, одновременные пользователи, последовательности действий. В нашем случае - веб-интерфейс ERP: вход, открытие заказа, сохранение, формирование отчёта. Каждый из этих шагов записывается как отдельный запрос, потом всё это крутится с нужной конкурентностью.
Связка получилась удобная: SQLIO показывает, что умеет железо само по себе, JMeter - что происходит, когда поверх запускается реальная нагрузка.
Что нашли на дисках
Сервер БД - стандартная для 2006 года конфигурация: пара SATA-дисков в зеркале на встроенном контроллере материнской платы, Windows Server 2003, SQL Server 2005. Никакого выделенного RAID-контроллера.
SQLIO запустили с размером блока 8 КБ, случайное чтение, глубина очереди 32 - то, как SQL Server читает данные из пула страниц. Цифры вышли скромные. При имитации одновременной нагрузки от двух-трёх десятков сессий задержки на диске росли нелинейно. IOPS упирались в потолок раньше, чем CPU даже начинал шевелиться.
Встроенный контроллер без кеша - это, по сути, запись в «голое железо» без буферизации. Каждый fsync ждёт физической головки. На OLTP-нагрузке, где SQL Server активно пишет в журнал транзакций, это узкое место очевидно.
Что показал JMeter
Сценарий: 80 виртуальных пользователей, рабочий день восемь часов, нагрузка распределена с пиком в утреннее время. JMeter гнал сессии через веб-интерфейс ERP.
Первые двадцать минут - нормально. Потом время отклика на операции с заказами начало расти. Не падало, не выдавало ошибок - просто медленнело. Открытие заказа вместо двух секунд - пять, потом восемь. Операция сохранения с обновлением связанных таблиц - до двенадцати секунд в пике.
Посмотрели на SQL Server: ожидания типа WRITELOG в топе. Журнал транзакций писался медленно из-за тех самых дисков.
Что сделали
Решение скучное, но рабочее: добавили выделенный RAID-контроллер с батарейным кешем на 256 МБ. Диски те же самые, контроллер другой - с включённым write-back кешем. Запись в журнал транзакций теперь уходит в быструю кеш-память контроллера и подтверждается мгновенно, а на физические диски сбрасывается уже контроллером в фоне.
Перегнали SQLIO - IOPS на случайной записи выросли кратно. Повторили JMeter-сценарий - время отклика вернулось к нормальному и держалось стабильно на протяжении всего теста. WRITELOG из топа ожиданий исчез.
Запуск прошёл штатно.
Пара наблюдений по итогу
Встроенный контроллер в RAID-зеркале не равно нормальный RAID. Зеркало защищает от потери диска, но производительность записи у такого решения слабая. Для файлового сервера с медленными пользователями - сойдёт. Для OLTP-базы с журналом транзакций - нет.
SQLIO стоит запускать до закупки железа, а не после. Тест занимает полчаса и показывает реальные характеристики дисковой подсистемы. Если делать это на этапе проектирования, можно заложить нужный контроллер сразу, а не доставлять его за неделю до запуска.
JMeter требует времени на подготовку сценария. Записать реальные HTTP-сессии, расставить таймеры, настроить assertions - это не час работы. В нашем случае на подготовку ушло два дня. Зато результат - не синтетика, а близкое к реальному поведение пользователей.
Для проектов, где аналитика и транзакционная нагрузка живут на одном сервере, диагностика дисковой подсистемы особенно важна: OLAP-запросы умеют читать данные большими последовательными блоками и легко забивают I/O под ноль, пока транзакционный слой ждёт своей очереди. Про то, как мы выстраиваем такие решения в части хранилищ и аналитики, - на странице DWH и бизнес-аналитика.
- Ночная витрина: утром свежие цифры вместо звонка аналитику · 13 декабря 2005
- Excel висит, куб летит: гонка отчётов на 400 тысячах строк · 20 марта 2006