Конкретные способы тестирования MySQL на примере

Способы тестирования (бенчмаркинга) MySQLЗакончив с общими вопросами (зачем нужно тестировать сервер MySQL и стратегия измерения производительности), давайте перейдем к конкретике — к тому, как проек­тировать и выполнять эталонные тесты. Однако прежде, чем обсуждать, как правильно выполнять эталонное тестирование, рассмотрим распространенные ошибки, которые могут привести к неподходящим или неточным результатам.

Простое предотвращение этих ошибок поможет вам значительно улучшить качество результатов.

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

 


Проектирование и планирование эталонных тестов

Первым шагом при планировании эталонных тестов является определение проблемы и цели. Затем следует решить, использовать ли стандартный эталонный тест или разработать собственный.

Если вы используете стандартный эталонный тест, выберите тот, который соответ­ствует вашим потребностям. Например, не применяйте эталонный тест ТРС-Н для системы электронной коммерции. По словам создателей, «ТРС-Н — это специальное решение, поддерживающее эталонное тестирование». Следовательно, такие тесты не подходят для OLTP-систем.

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

Затем вам потребуются запросы к данным. Вы можете превратить комплект модуль­ных тестов в простейший эталонный тест, просто прогнав его много раз, но вряд ли это соответствует тому, как реально используется база данных. Лучше записать все запросы в рабочей системе в течение репрезентативного отрезка времени, напри­мер в течение часа в период пиковой нагрузки или в течение всего дня. Если будут записаны запросы за малый промежуток времени, возможно, вам потребуется не­сколько таких периодов. Это охватит все действия системы, такие как запросы для еженедельного отчета или работа в пакетном режиме, которую вы запланировали на часы минимальной загрузки.

Вы можете записывать запросы на нескольких уровнях. Например, если требуется выполнить эталонное полностековое тестирование, то можно протоколировать HTTP-запросы на веб-сервере. Или включить журнал запросов MySQL. Но если вы будете воспроизводить запросы из журнала, не забудьте создать отдельные по­токи, а не просто последовательно повторяйте запросы один за другим. Также важно создавать отдельный поток в журнале для каждого соединения вместо хаотичных запросов в разных потоках. В журнале запросов видно, на каком соединении был выполнен каждый запрос.

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

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


Должно ли быть длительным эталонное тестирование?

Важно, чтобы эталонное тестирование занимало разумное время. Если вы заинтере­сованы в стабильной работе системы, а наверняка это так, то необходимо наблюдать ее в устойчивом состоянии. Это может потребовать неожиданно много времени, осо­бенно на серверах с большим количеством данных и объемной памятью. В большин­стве систем есть несколько буферов, которые создают наращиваемую мощность — способность амортизировать пики, откладывая некоторую работу и выполняя ее позже, после того как нагрузка схлынет. Но если вы задействуете эти механизмы в течение длительного времени, буферы переполнятся и вы в конце концов увидите, что система не может выдерживать краткосрочную максимальную нагрузку.

Иногда неизвестно, как долго должен выполняться эталонный тест. В этом случае можете просто запустить его, не ограничивая время, и наблюдать, пока не удосто­веритесь, что система начала стабилизироваться. Далее приведен пример того, как мы это делали в незнакомой системе. На рис. 1 показан график временных рядов пропускной способности чтения и записи на диск.

По мере прогрева системы (после 3-4 часов работы) линия, характеризующая про­цесс чтения, стала устойчивой, тогда как линия, показывающая запись, демонстриро­вала резкие колебания на протяжении по меньшей мере 8 часов. И даже после этого на графике есть несколько резких колебаний. В дальнейшем процессы как чтения, так и записи, судя по всему, стабилизировались. Эмпирическое правило гласит: ждите, пока система не станет выглядеть устойчивой, по крайней мере на протяжении вре­мени, требующегося для ее разогрева. Мы проводили этот эталонный тест в течение 72 часов, чтобы гарантировать, что получили характеристику поведения системы в долгосрочной перспективе.

Производительность ввода/вывода во время расширенного эталонного тестирования

Рис. 1. Производительность ввода/вывода во время расширенного эталонного тестирования

Очень распространенная ошибка при эталонном тестировании заключается в том, чтобы запустить серию коротких тестов, например по 60 секунд, и на их основании сделать вывод о производительности системы. Мы слышим много комментариев, та­ких как «Я попытался провести эталонное тестирование новой версии сервера, и она оказалась не быстрее старой». Изучая реальные эталонные тесты, мы часто обнару­живаем, что они выполнены таким способом, на основании которого нельзя делать подобные выводы. Иногда люди говорят, что у них просто нет времени для эталонного тестирования в течение 8 или 12 часов на десяти различных уровнях параллелизма на двух или трех версиях сервера. Если у вас нет времени для правильного эталонного тестирования, то время на него вы потратили впустую: лучше доверять чужому опыту, чем делать неполный эталонный тест и получать неправильные результаты.

 


Фиксация производительности и состояния системы

Важно собрать во время эталонного тестирования как можно больше информации о тестируемой системе (SUT). Грамотный подход состоит в создании базового ката­лога с подкаталогами для результатов каждого запуска. После этого можете поместить результаты, файлы конфигурации, измерения, скрипты и заметки для каждого за­пуска в соответствующий подкаталог. Если вы получили больше данных, чем вас интересует, запишите их. Гораздо лучше иметь ненужные данные, чем пропустить что-то важное: возможно, дополнительные данные пригодятся в будущем. Попробуй­те записать показатели состояния и производительности, такие как использование ЦП, дисковый ввод/вывод, статистика сетевого трафика, счетчики из SHOW GLOBAL STATUS и т. д.

Приведем пример сценария оболочки, который вы можете использовать для сбора данных по MySQL во время эталонного тестирования:

#!/bin/sh
INTERVAL=5
PREFIX=$INTERVAL-sec-status
RUNFILE=/home/benchmarks/running
mysql -e 'SHOW GLOBAL VARIABLES' >> mysql-variables
while test -e $RUNFILE; do
   file=$(date +%F_%I)
   sleep=$(date +%s.%N | awk "{print $INTERVAL - (\$1 % $INTERVAL)}")
   sleep $sleep
   ts="$(date +"TS %s.%N %F %T")"
   loadavg="$(uptime)"
   echo "$ts $loadavg" >> $PREFIX-${file}-status
   mysql -e 'SHOW GLOBAL STATUS' >> $PREFIX-${file}-status &
   echo "$ts $loadavg" >> $PREFIX-${file}-innodbstatus
   mysql -e 'SHOW ENGINE INNODB STATUS\G' >> $PREFIX-${file}-innodbstatus &
   echo "$ts $loadavg" >> $PREFIX-${file}-processlist
   mysql -e 'SHOW FULL PROCESSLIST\G' >> $PREFIX-${file}-processlist &
   echo $ts
done
echo Exiting because $RUNFILE does not exist.

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

Это всего лишь короткий фрагмент кода, который в текущем виде вряд ли удовлет­ворит вашим запросам, однако он иллюстрирует правильный подход к сбору данных о производительности и состоянии. Скрипт фиксирует лишь несколько видов данных в MySQL, но вы легко можете добавить к нему больше элементов. Например, можете фиксировать /ргос/diskstats для записи дискового ввода/вывода с целью последу­ющего анализа с помощью инструмента pt-diskstats.

 


Получение точных результатов тестов

Наилучший способ получить точные результаты — спроектировать эталонный тест таким образом, чтобы он отвечал именно на те вопросы, которые вы хотите задать. Тот ли эталонный тест вы выбрали? Собирает ли он данные, которые нужны для от­вета на поставленный вопрос? Не проводится ли эталонное тестирование по непра­вильным критериям? Например, не запускаете ли вы тест, нагружающий процессор, для прогнозирования производительности приложения, которое, как вы знаете, будет ограничено пропускной способностью систем ввода/вывода?

Затем убедитесь в повторяемости результатов эталонного тестирования. Попытай­тесь удостовериться, что система находится в одном и том же состоянии перед каждым прогоном теста. Если эталонный тест особо важен, каждый раз перед его запуском перезагружайте компьютер. Если нужно провести эталонное тестиро­вание на прогретом сервере, что является нормой, то необходимо убедиться, что сервер прогревался достаточно долго (см. предыдущий раздел о том, как долго следует выполнять эталонное тестирование) и что эта процедура воспроизводима. Так, если прогрев состоит из случайных запросов, то результаты теста нельзя будет повторить.

Если тест изменяет данные или схему, восстанавливайте их из снимка между прого­нами теста. Вставка в таблицу с тысячей строк не даст того же результата, что вставка в таблицу с миллионом строк! Фрагментация и определенное расположение данных на диске также могут сделать результаты невоспроизводимыми. Один из способов убедиться, что физическое расположение будет почти одинаковым, — быстро от­форматировать и скопировать сегмент.

Следите за внешней нагрузкой, системами профилирования и мониторинга, подроб­ной записью в журналы, периодическими заданиями и прочими факторами, которые могут исказить результаты. Типичными сюрпризами являются запуск задания cron в середине теста, или периодическое автоматическое «патрулирование», или заплани­рованная проверка целостности RAID-массива. Убедитесь, что все необходимые для эталонного теста ресурсы на время его исполнения выделены только ему. Если сеть загружена еще какой-то работой или эталонный тест запущен на SAN-устройстве, которое одновременно используется и другими серверами, результаты могут ока­заться неточными.

Постарайтесь менять как можно меньше параметров при каждом выполнении эта­лонного тестирования. Если вы измените сразу несколько факторов, то рискуете что-то упустить. Кроме того, параметры могут зависеть друг от друга, поэтому ино­гда их нельзя изменять независимо. В ряде случаев вы можете даже не подозревать о существовании такой зависимости, что лишь усложняет дело.

Лучше всего менять параметры тестирования итеративно, а не вносить значительные изменения между прогонами. Например, если вы пытаетесь настроить сервер на специфическое поведение, используйте технику «разделяй и властвуй» (уменьшай­те или увеличивайте значение параметра вдвое на каждой последующей итерации тестирования).

Мы видели множество эталонных тестов, которые пытаются предсказать произво­дительность после миграции, например, с Oracle на MySQL. Зачастую результаты этих тестов ненадежны, поскольку MySQL эффективно работает с совершенно иными типами запросов, чем Oracle. Если вы захотите узнать, насколько хорошо написанное для Oracle приложение будет работать после миграции на MySQL, то вам, скорее всего, придется перепроектировать схему и запросы с учетом специфики MySQL. (Возможно, иногда, например при разработке кросс-платформенного при­ложения, вам понадобится узнать, как одни и те же запросы будут работать на обеих платформах, но такое случается редко.)

В любом случае нельзя получить осмысленные результаты с параметрами настройки MySQL по умолчанию, поскольку они рассчитаны на небольшие приложения, ко­торые потребляют очень мало памяти. Самый большой стыд мы испытывали, когда кто-то публиковал ошибочные эталонные тесты, сравнивающие MySQL с другими системами управления реляционными базами данных (СУРБД), с настройками по умолчанию. Кажется, что эталонные тесты новичков часто становятся главными новостями.

Твердотельные хранилища данных (SSD и PCIe-карты) создают особые проблемы для эталонного тестирования.

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

 


Прогон эталонного теста и анализ результатов

После того как вы все подготовили, пора запускать тест, чтобы начать сбор и анализ данных.

Обычно имеет смысл автоматизировать прогоны эталонного теста. Это улучшит ре­зультаты и их точность, поскольку не позволит забыть о каких-то шагах и исключит различия в методике прогона теста. А заодно поможет документировать весь процесс.

Подойдет любой метод автоматизации, например Makefile или набор пользователь­ских скриптов. Выберите любой устраивающий вас язык для написания скриптов: shell, PHP, Perl и т. д. Попытайтесь наиболее полно автоматизировать процедуру тестирования, включая загрузку данных, прогрев системы, запуск эталонного теста и запись результатов.

 

Правильно настроенное эталонное тестирование может стать одношаговым процессом. Если вы просто запускаете одноразовый эталонный тест, чтобы что-то быстро проверить, автоматизировать его нет смысла. Однако если предполагаете вернуться к его результатам в будущем, обязательно автоматизируйте его. Не сделав этого, вы никогда не вспомните, как запускали эталонный тест и какие параметры указывали, так что в дальнейшем не сможете воспользоваться результатами эталонного тестирования.

 

Обычно эталонный тест выполняют несколько раз. Конкретное количество итераций зависит от методологии оценки результатов и от того, насколько эти результаты важ­ны. Если нужно быть совершенно уверенными в итогах тестирования, следует про­гнать тест большее количество раз. Обычно для оценки применяют такие методики: нахождение лучшего результата, вычисление среднего значения по всем полученным итогам или просто выполнение эталонного теста пять раз и вычисление среднего результата по трем лучшим. Степень точности вы определяете сами. Возможно, вы захотите применить к результатам статистические методы, найти доверительный интервал и т. д., но обычно такой уровень точности не требуется. Если тест удов­летворительно отвечает на ваши вопросы, можно просто прогнать его несколько раз и посмотреть, насколько различаются полученные значения. Если различие велико, следует либо увеличить количество прогонов, либо запустить тест на больший период времени, что, как правило, приводит к уменьшению разброса результатов.

После того как результаты получены, необходимо их проанализировать, то есть превратить числа в знания. Цель — получить ответы на вопросы, ради которых го­товилась тестовая инфраструктура. Идеально было бы, если бы на выходе формулировались утверждения наподобие «модернизация сервера до четырехпроцессорного увеличит пропускную способность на 50 % при неизменном времени отклика» или «использование индексов ускорило выполнение запросов». Если вы хотите реализо­вать научный подход к этому вопросу, почитайте о нулевой гипотезе до проведения эталонного тестирования, однако имейте в виду, что вряд ли большинство людей ожидают от вас такого высокого уровня.

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

#!/bin/sh
# This script converts SHOW GLOBAL STATUS into a tabulated format, one line
# per sample in the input, with the metrics divided by the time elapsed
# between samples.
awk '
   BEGIN {
      printf "#ts date time load QPS";
      fmt = " %.2f";
   }
   /^TS/ { # The timestamp lines begin with TS.
      ts = substr($2, 1, index($2, ".") - 1);
      load = NF - 2;
      diff = ts - prev_ts;
      prev_ts = ts;
      printf "\n%s %s %s %s", ts, $3, $4, substr($load, 1, length($load)-1);
   }
   /Queries/ {
      printf fmt, ($2-Queries)/diff;
      Queries=$2
   }
' "$@"

Если вы назовете скрипт analyze и запустите его для файла статуса, сгенерирован­ного предыдущим скриптом, то можете получить примерно следующее:

[baron@ginger ~]$ ./analyze 5-sec-status-2011-03-20
#ts date time load QPS
1300642150 2011-03-20 17:29:10 0.00 0.62
1300642155 2011-03-20 17:29:15 0.00 1311.60
1300642160 2011-03-20 17:29:20 0.00 1770.60
1300642165 2011-03-20 17:29:25 0.00 1756.60
1300642170 2011-03-20 17:29:30 0.00 1752.40
1300642175 2011-03-20 17:29:35 0.00 1735.00
1300642180 2011-03-20 17:29:40 0.00 1713.00
1300642185 2011-03-20 17:29:45 0.00 1788.00
1300642190 2011-03-20 17:29:50 0.00 1596.40

Первая строка содержит заголовки столбцов. На вторую строку не обращайте вни­мания, поскольку она появляется до запуска эталонного теста. Последующие строки содержат метку времени Unix, дату, время (обратите внимание на то, что данные по­являются через пятисекундные интервалы, как говорилось ранее), среднюю загрузку системы и, наконец, количество запросов в секунду (QPS), выполненных сервером базы данных. Это минимальный набор данных, необходимый для изучения произ­водительности системы. Далее покажем, как быстро построить график и посмотреть, что произошло во время эталонного тестирования.

 


Важность построения графика тестирования

Чтобы управлять миром, надо непрерывно строить графики.  Но если серьезно, самое простое и полезное, что вы можете сделать с показателями производи­тельности системы, — это представить их в виде временного ряда и посмотреть на них.

На графике вы можете сразу выявить проблемы, даже те, которые трудно или не­возможно увидеть, исследуя необработанные данные. Вы должны противостоять соблазну просто взглянуть на средние значения и другие сводные статистические данные, которые может выдать инструмент эталонного тестирования. Средние значения бесполезны, потому что скрывают то, что происходит на самом деле. К сча­стью, вывод, осуществляемый написанными нами скриптами, легко настраивается для таких инструментов, как gnuplot или R, для создания графика в мгновение ока. Мы продемонстрируем использование gnuplot, предположив, что вы сохранили данные в файл под названием QPS-per-5-seconds:

gnuplot> plot "QPS-per-5-seconds" using 5 w lines title "QPS"

Эта строка — указание gnuplot создать в файле пятое поле (поле QPS) с линиями, на­звать его QPS и отобразить на графике. На рис. 2 представлен результат.

 

Построение графика по эталонному тесту QPS

Рис. 2Построение графика по эталонному тесту QPS

Теперь рассмотрим пример, который еще более ярко продемонстрирует важность построения графиков. Предположим, система страдает от так называемого яростного сброса, когда она отстает от проверки и блокирует всю активность до тех пор, пока не нагонит ее, что приводит к резким падениям пропускной способности. Девяносто пятый процентиль и среднее время отклика не покажут падений, поэтому результаты скроют проблему. Однако на графике периодические снижения активности отобра­зятся (рис. 3).

Результаты 30-минутного прогона эталонного теста dbt2

Рис. 3. Результаты 30-минутного прогона эталонного теста dbt2

Здесь демонстрируется пропускная способность транзакции в минуту для нового заказа (NOTPM). Эта линия показывает значительные падения, которые график среднего значения (пунктирный) не покажет совсем. Первое падение связано с тем, что кэши сервера еще не прогреты. Другие отражают ситуацию, когда сервер тратит время, интенсивно сбрасывая «грязные» страницы на диск. Без графика трудно об­наружить эти отклонения.

Такие пики часто встречаются в сильно нагруженных системах и требуют изучения. В данном случае такое поведение связано с использованием более старой версии InnoDB, которая имела несовершенный алгоритм сброса. Но нельзя считать это само собой разумеющимся. Следует вернуться к подробной статистике и просмотреть ее. Как выглядел результат SHOW ENGINE INNODB STATUS во время этих снижений актив­ности? А как насчет вывода SHOW FULL PROCESS LIST? Возможно, вы сразу увидите, что InnoDB выполняла сброс или что в списке процессов было много потоков со статусом «ожидание в очереди из-за блокировки кэша» или подобным. Вот почему полезно очень подробно фиксировать данные во время тестов, а затем строить гра­фики для обнаружения проблем.

Теперь настало время познакомиться с конкретными инструментами и утилитами для тестирования MySQL.

Вас заинтересует / Intresting for you:

Модель развития базы данных My...
Модель развития базы данных My... 1417 просмотров Ирина Светлова Thu, 10 Jan 2019, 12:29:03
Выбор оптимальных типов данных...
Выбор оптимальных типов данных... 9767 просмотров Валерий Павлюков Sun, 27 Oct 2019, 15:24:19
Транзакции в базе данных MySQL
Транзакции в базе данных MySQL 21508 просмотров Ирина Светлова Mon, 07 Jan 2019, 05:18:23
Обзор архитектуры MySQL
Обзор архитектуры MySQL 4568 просмотров Ирина Светлова Wed, 09 Jan 2019, 04:25:21
Печать
Войдите чтобы комментировать