Тестирование дисковой системы в Linux

10/08/2021

hdd_test_img

Основные аппаратные ресурсы любого серверного оборудования — это процессор, ОЗУ и дисковая подсистема. Определение их производительности и мониторинг — одни из ключевых задач в эксплуатации такой техники. Тут хотелось бы остановиться на вопросе определения производительности дисковой подсистемы. При этом под таковой я подразумеваю не только один обычный жесткий диск, но и различные сложные системы для хранения данных, которые используются в серверных системах. Современные программно определяемые стораджи настолько далеко ушли в технологиях, что нет смысла в данном контектсе останавливаться на специфике их работы. Давайте рассмотрим ситуацию, когда у нас есть виртуальная или физическая машина с ОС Linux, на которой доступен физический или логический жесткий диск, производительность которого хотелось бы протестировать. Для этих целей идеально подходит небольшая утилита fio. Она очень гибкая и богатая по фунционалу. Позволяет провести разнообразные тесты ввода-вывода дисковых подсистем.

Проведение тестов

Итак, давайте посмотрим, как мы можем использовать fio, чтобы оценить производительность конкретной дисковой подсистемы. Для начала, нужно установить данную утилиту в системе. Так, в операционной системе Ubuntu Linux 18.04/20.04 это можно сделать следующим образом.

# sudo apt update
# sudo apt install fio

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

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

# fio --name=fiotest01 --ioengine=libaio --rw=read --direct=1 --size=1G --runtime=240 --group_reporting --directory=/tmp/fio/

fiotest01: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
fio-3.16
Starting 1 process
fiotest01: Laying out IO file (1 file / 1024MiB)
Jobs: 1 (f=1): [R(1)][100.0%][r=3311KiB/s][r=827 IOPS][eta 00m:00s]
fiotest01: (groupid=0, jobs=1): err= 0: pid=292277: Tue Aug 10 08:37:37 2021
  read: IOPS=772, BW=3091KiB/s (3165kB/s)(724MiB/240001msec)
    slat (usec): min=10, max=643, avg=24.35, stdev= 8.56
    clat (usec): min=243, max=530802, avg=1266.70, stdev=4813.97
     lat (usec): min=305, max=530827, avg=1291.71, stdev=4814.60
    clat percentiles (usec):
     |  1.00th=[   355],  5.00th=[   420], 10.00th=[   478], 20.00th=[   594],
     | 30.00th=[   676], 40.00th=[   742], 50.00th=[   799], 60.00th=[   848],
     | 70.00th=[   898], 80.00th=[   971], 90.00th=[  1090], 95.00th=[  1483],
     | 99.00th=[ 12911], 99.50th=[ 19530], 99.90th=[ 57934], 99.95th=[ 88605],
     | 99.99th=[206570]
   bw (  KiB/s): min=    8, max= 6978, per=99.99%, avg=3089.62, stdev=1263.49, samples=479
   iops        : min=    2, max= 1744, avg=772.39, stdev=315.88, samples=479
  lat (usec)   : 250=0.01%, 500=12.27%, 750=29.09%, 1000=42.49%
  lat (msec)   : 2=12.11%, 4=0.69%, 10=1.97%, 20=0.90%, 50=0.36%
  lat (msec)   : 100=0.08%, 250=0.04%, 500=0.01%, 750=0.01%
  cpu          : usr=0.71%, sys=2.76%, ctx=185945, majf=0, minf=14
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=185440,0,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
   READ: bw=3091KiB/s (3165kB/s), 3091KiB/s-3091KiB/s (3165kB/s-3165kB/s), io=724MiB (760MB), run=240001-240001msec

Disk stats (read/write):
    dm-0: ios=185315/149, merge=0/0, ticks=233360/5320, in_queue=238680, util=100.00%, aggrios=185440/119, aggrmerge=0/30, aggrticks=235232/4512, aggrin_queue=85892, aggrutil=99.99%
  sda: ios=185440/119, merge=0/30, ticks=235232/4512, in_queue=85892, util=99.99%

В вышеприведенной команде, мы запустили тест на последовательное чтение, что указано в параметре —rw=read. Кроме этого, мы использовали параметр —ioengine=libaio, что заставляет fio использовать библиотеку libaio при тестировании. На сегодняшний момент эта библиотека является лучшим вариантом для получения точных данных о производительности дисковой подсистемы в ОС Linux. Также опция —direct=1 указывает на то, что не надо использовать буфферизацию при выполнении команды. При этом указав —size=1G, мы обозначили размер файла, который будет использован при тестировании, а с помощью —runtime=240, мы ограничили выполнение команды 240 секундами.

Отдельно стоит глубже осветить параметр —rw команды fio. С помощью данной опции мы можем указать, какой тип операций ввода-вывода будет использоваться. Доступны следующие варианты: последовательное чтение (read), случайное чтение (randread), последовательная запись (write), случайна запись (randwrite), а также одновременное использование операций чтения и записи (readwrite). В зависимости от планируемого типа нагрузки, нужно проводить какие-то определенные тесты по типу IOPS, либо все возможные варианты.

Теперь давайте рассмотрим реальный случай использования данной утилиты. Задействуем сразу несколько одновременных процессов, а также создадим глубину очереди IOPS в 16. В данном примере мы проведем тест на последовательную запись. Сама команда и ее вывод приведены ниже. При этом опять будем использовать директорию /tmp/fio для проведения тестов.

# fio --name=fiotest02 --ioengine=libaio --iodepth=16 --rw=write --bs=4k --direct=1 --size=4G --numjobs=4 --runtime=240 --group_reporting --directory=/tmp/fio/

fiotest02: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=16
...
fio-3.16
Starting 4 processes
fiotest02: Laying out IO file (1 file / 4096MiB)
fiotest02: Laying out IO file (1 file / 4096MiB)
fiotest02: Laying out IO file (1 file / 4096MiB)
fiotest02: Laying out IO file (1 file / 4096MiB)
Jobs: 4 (f=4): [W(4)][100.0%][w=3603KiB/s][w=900 IOPS][eta 00m:00s]
fiotest02: (groupid=0, jobs=4): err= 0: pid=293062: Tue Aug 10 12:19:09 2021
  write: IOPS=871, BW=3485KiB/s (3568kB/s)(817MiB/240050msec); 0 zone resets
    slat (usec): min=11, max=147475, avg=33.16, stdev=769.51
    clat (msec): min=7, max=1508, avg=73.42, stdev=63.70
     lat (msec): min=7, max=1508, avg=73.46, stdev=63.70
    clat percentiles (msec):
     |  1.00th=[   17],  5.00th=[   18], 10.00th=[   18], 20.00th=[   24],
     | 30.00th=[   31], 40.00th=[   44], 50.00th=[   61], 60.00th=[   73],
     | 70.00th=[   89], 80.00th=[  110], 90.00th=[  146], 95.00th=[  180],
     | 99.00th=[  313], 99.50th=[  393], 99.90th=[  542], 99.95th=[  609],
     | 99.99th=[  802]
   bw (  KiB/s): min=  408, max= 8688, per=100.00%, avg=3491.23, stdev=376.01, samples=1916
   iops        : min=  102, max= 2172, avg=872.73, stdev=94.01, samples=1916
  lat (msec)   : 10=0.04%, 20=14.82%, 50=28.91%, 100=31.94%, 250=22.45%
  lat (msec)   : 500=1.70%, 750=0.12%, 1000=0.03%, 2000=0.01%
  cpu          : usr=0.11%, sys=0.61%, ctx=85872, majf=0, minf=50
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=0,209126,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=16

Run status group 0 (all jobs):
  WRITE: bw=3485KiB/s (3568kB/s), 3485KiB/s-3485KiB/s (3568kB/s-3568kB/s), io=817MiB (857MB), run=240050-240050msec

Disk stats (read/write):
    dm-0: ios=0/209796, merge=0/0, ticks=0/15231692, in_queue=15231692, util=99.95%, aggrios=0/209402, aggrmerge=0/535, aggrticks=0/15186568, aggrin_queue=14782288, aggrutil=99.94%
  sda: ios=0/209402, merge=0/535, ticks=0/15186568, in_queue=14782288, util=99.94%

И напоследок, рассмотрим случай использования утилиты fio, при которой будет производится запись напрямую на диск. При этом данные на /dev/sdb1, который используется в этом примере, будут повреждены. При осуществлении подобных тестов нужно быть особенно осторожным. Пример такой команды и ее вывод в командной строке Linux привиден далее по тексту.

# fio --name=fiotest03 --ioengine=libaio --iodepth=16 --rw=write --bs=4k --direct=1 --size=4G --runtime=240 --group_reporting --filename=/dev/sdb1

fiotest03: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=16
fio-3.16
Starting 1 process
Jobs: 1 (f=1): [W(1)][100.0%][w=6756KiB/s][w=1689 IOPS][eta 00m:00s]
fiotest03: (groupid=0, jobs=1): err= 0: pid=293329: Tue Aug 10 12:58:44 2021
  write: IOPS=1778, BW=7115KiB/s (7285kB/s)(1668MiB/240009msec); 0 zone resets
    slat (usec): min=2, max=571, avg=10.08, stdev= 8.71
    clat (msec): min=2, max=411, avg= 8.98, stdev= 7.23
     lat (msec): min=2, max=411, avg= 8.99, stdev= 7.23
    clat percentiles (msec):
     |  1.00th=[    5],  5.00th=[    6], 10.00th=[    6], 20.00th=[    7],
     | 30.00th=[    8], 40.00th=[    8], 50.00th=[    9], 60.00th=[    9],
     | 70.00th=[   10], 80.00th=[   11], 90.00th=[   13], 95.00th=[   14],
     | 99.00th=[   18], 99.50th=[   21], 99.90th=[  117], 99.95th=[  167],
     | 99.99th=[  305]
   bw (  KiB/s): min= 1888, max=11488, per=100.00%, avg=7114.10, stdev=1402.75, samples=480
   iops        : min=  472, max= 2872, avg=1778.51, stdev=350.69, samples=480
  lat (msec)   : 4=0.55%, 10=72.74%, 20=26.16%, 50=0.35%, 100=0.07%
  lat (msec)   : 250=0.12%, 500=0.02%
  cpu          : usr=0.99%, sys=2.40%, ctx=108948, majf=0, minf=12
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=0,426889,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=16

Run status group 0 (all jobs):
  WRITE: bw=7115KiB/s (7285kB/s), 7115KiB/s-7115KiB/s (7285kB/s-7285kB/s), io=1668MiB (1749MB), run=240009-240009msec

Disk stats (read/write):
  sdb: ios=29/426695, merge=0/0, ticks=52/3815361, in_queue=2955868, util=100.00%

Заключение

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *