Для измерения скорости произвольного доступа хранилища данных, тех самых пресловутых IOPS, я использую утилиту IOzone. Вообще, это чрезвычайно мощный инструмент, способный в умелых руках протестировать подробнейшим образом работу как физических носителей, так и файловых систем. Со всеми возможностями iozone можно познакомиться, прочитав объемную документацию. Установить программу можно либо с помощью штатного пакетного менеджера (если такой пакет есть для вашей ОС), либо собрав ее из исходников.
Для быстрой оценки производительности «на каждый день» я использую примерно такую команду:
iozone -O -i0 -i2 -s4g -r4k
Параметр -O задает вывод результата в IOPS, вместо KB/s. Параметр -i0 запускает тест линейной записи. Вообще, нам этот тест не нужен, но обойтись без него нельзя, так как с его помощью iozone создает рабочий файл для дальнейших тестов. Параметр -i2 запускает собственно тестирование произвольного чтения и записи. Параметр -s задает размер рабочего файла, в данном случае 4 GB; поддерживаются суффиксы: k (килобайты), m (мегабайты) и т. д. И, наконец, параметр -r задает размер блока данных, которые пишутся или читаются за одну операцию. Рассмотрим подробнее каждый из параметров на примере тестирования диска виртуальной машины в облаке.
Перед тестированием нужно создать на физическом носителе файловую систему и смонтировать ее (все происходит на Linux).
# mkfs.ext3 /dev/sda3 # mount /dev/sda3 /mnt # cd /mnt
Здесь имя sda3 означает не третий раздел диска sda, а отдельный третий виртуальный диск, такая вот нумерация. Как видно, я размечаю файловую систему прямо по всему носителю, без создания таблицы разделов. Linux к этому относится спокойно, правда, для настоящих дисков выдает предупреждение:
/dev/sda is entire device, not just one partition! Proceed anyway? (y,n)
Наверное, выбор файловой системы слегка влияет на результат, но не думаю, что значительно. Поэтому для всех тестов я использую старую добрую EXT3.
Если нужно протестировать не физический носитель (диск или RAID массив), а, скажем, кластерную файловую систему (например GPFS), то достаточно просто перейти в открытую на запись директорию, в которую смонтирована тестируемая ФС.
В принципе, можно тестировать и без ФС, непосредственно физический носитель. Для этого достаточно с помощью ключа -f установить в качестве рабочего файла файл блочного устройства, например /dev/sda. Но при этом смысл результатов будет неясным, ведь использовать в дальнейшем диск мы все равно будем в связке с файловой системой.
С параметром -O все ясно. По умолчанию iozone выдает результат в виде скорости чтения или записи, и для получения количества операций в секунду эту скорость нужно делить на размер блока. С -O получаем сразу нужный результат. Параметр -i также не вызывает вопросов.
Размер файла следует выбирать не менее объема физической памяти, чтобы избежать влияния кэша ОС. На тестируемой машине 4 GB ОЗУ, поэтому размер файла нужно взять тоже 4 GB. Можно и больше, но это увеличит время теста. Влияние кэша легко увидеть, задав меньший объем файла и посмотрев на результаты повторной записи и чтения.
# iozone -i0 -i1 -s1g -r64k KB reclen write rewrite read reread 1048576 64 780190 1783292 4519722 5242880
Тесты i0 и i1, помимо записи и чтения, делают еще и повторные запись и чтение (rewrite и reread). Видно, что повторная запись проходит в 2 раза быстрее изначальной, а чтение выдает вообще космическую скорость — 5 GB/s. Все это — результат работы кэша. Теперь увеличим размер файла до 4 GB.
# iozone -i0 -i1 -s4g -r64k KB reclen write rewrite read reread 4194304 64 104857 79715 61255 53635
Вот теперь результаты похожи на правду. Повторная запись даже слегка медленней первоначальной, а скорость чтения в районе 50-60 MB/s.
Если тестируется кластерная файловая система, то при выборе размера файла следует также принимать во внимание размер кэша на нодах кластера. Допустим, на каждой ноде есть по 10 GB кэша, тогда и размер файла должен быть не менее 10 GB, а лучше еще больше.
Определившись с размером файла, переходим к размеру блока. Так как мы меряем количество операций ввода-вывода в секунду, то чем меньше размер блока, тем выше будет результат, так как блоки большего размера требуют больше времени для передачи. Реальные приложения оперируют блоками от 4 до 64 KB. Для получения максимально возможного для данного носителя результата, необходимо брать блок размером 4, а то и 2 или 1 KB. Но тут есть одно «но». Подобный тест может занять значительное время, так как файл должен быть полностью покрыт блоками. Допустим, мы тестируем SATA диск, и надеемся получить от него около 100 IOPS. Тогда для файла размером 4 GB и блока 4 KB время теста составит 4 * 1024 * 1024 / (4 * 100) = 10485 секунд, то есть около трех часов. Часто результат нужно получить быстро, пусть и не очень точно. В таком случае нужно либо уменьшать размер файла, что крайне нежелательно, либо увеличивать размер блока. С блоком в 64 KB прогнозируемое время теста будет в 16 раз меньше, то есть около 10 минут, что уже вполне приемлемо. Полученный результат будет не сильно отличаться от максимально возможного, и на это можно будет сделать небольшую поправку.
Для начала я запускаю тест с минимальный блоком в 4 KB.
# iozone -O -i0 -i2 -s4g -r4k
После этого в другом терминале выполняю команду iostat 1, чтобы контролировать, что происходит. В начале создается файл линейной записью, и iostat показывает примерно такую картину.
avg-cpu: %user %nice %system %iowait %steal %idle 0.00 0.00 0.26 4.21 0.00 95.53 Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn sda1 0.00 0.00 0.00 0 0 sda2 0.00 0.00 0.00 0 0 sda3 786.00 0.00 68528.00 0 68528
Контролировать скорость создания файла можно его периодическим просмотром.
# ls -lh /mnt total 1.5G -rw-r----- 1 root root 1.5G 2011-01-11 16:19 iozone.tmp drwx------ 2 root root 16K 2011-01-11 15:20 lost+found
Если уже на этом этапе видно, что файл создается очень медленно, а результат нужно получить быстро, увеличиваем размер блока.
Когда параметр Blk_wrtn/s станет 0, это значит, что запись файла закончена, и начался тест случайного чтения. Параметр Blk_read/s при этом станет отличным от нуля.
avg-cpu: %user %nice %system %iowait %steal %idle 0.00 0.00 0.00 14.16 0.00 85.84 Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn sda1 0.00 0.00 0.00 0 0 sda2 0.00 0.00 0.00 0 0 sda3 540.91 4355.29 0.00 880 0
Теперь нужно посмотреть на параметр tps и определить его среднее значение. Это будет текущая скорость чтения в IOPS. На основании нее по вышеприведенной формуле можно прикинуть, сколько времени займет тест; и если оно слишком велико, увеличить размер блока.
Такой контроль предварительных результатов позволяет оперативно подстроить параметры тестирования под ситуацию, чтобы не терять зря время. Однако, если времени навалом, можно сразу запускать тест с самым большим размером файла и самым маленьким размером блока и идти домой.
Собственно, для тестируемого диска блок в 4 KB оказался слишком маленьким, и я перезапустил тест с блоком в 64 K; через некоторое время результаты были готовы.
random random KB reclen write rewrite read reread read write 4194304 64 1961 2795 554 663
550 IOPS на чтение и 660 на запись. Блоками по 4 KB было бы еще больше.
В редких случаях одного потока не хватает, чтобы полностью нагрузить дисковый массив или кластерную файловую систему. Для таких случаев есть ключ -t, задающий количество одновременно работающих потоков. Количество потоков следует подобрать экспериментально, контролируя с помощью iostat рост IOPS с ростом числа потоков.
Для тестов ФС и дисков можно использовать прекрасную утилиту vdbench, с помощью которой можно обеспечить автоматизацию проведения множества синтетический тестов.