Утилита fio предназначена для выполнения нагрузочного тестирования дисковой подсистемы. При этом тесты могут быть достаточно разнообразными.

Об утилите

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

Так как эта утилита не предустановлена в систему, её нужно вначале установить. В Ubuntu 22.04 и в Debian 11 вы можете установить эту утилиту из стандартных репозиториев:

$ sudo apt install fio

Типичное использование fio выглядит следующем образом:

$ sudo fio <файл задания>

Файл задания — это описание теста, который утилита должна выполнить.

Получается, для того чтобы изучить работу fio, нужно научиться писать файлы заданий и читать отчеты о проделанных тестах.

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

Терминология

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

  • Когда приложение работает с данными, то оно читает или записывает эти данные блоками, в итоге операция ввода/вывода — это чтение или запись одного такого блока.
  • Однако, приложение может читать или писать блоки разного размера, поэтому размер блока — это тоже важный параметр.
  • Пропускная способность дисковой подсистемы измеряется в двух величинах:
    • B/s — количество байт в секунду, или производные (KB/s, MB/s);
    • IOPS — количество операций ввода/вывода в секунду.
  • Латентность — это время выполнения одной операции ввода/вывода. Причем, утилита fio определяет 3 разных показателя латентности:
    • slat — время необходимое на отправку запроса;
    • clat — временной промежуток после отправки запроса и до полной его обработки;
    • lat — время между тем как запрос был создан и до завершения его обработки.
  • Так как операции ввода/ввода вывода обрабатываются очень быстро, то расчет латентности ведется в usec (микросекундах), или в msec (миллисекундах).
  • Глубина очереди (iodepth). Когда система работает с диском, то одни запросы обрабатываются, а другие ждут в очереди. Грубо говоря, если iodepth=10, значит запрос находился в очереди в 10 раз дольше чем обрабатывался. А если быть точным то iodepth равняется сумме нахождения в очереди и обработке, делённой на время обработки. Если iodepth = 32, значит запрос находился в очереди 31 условную единицу времени а обрабатывался 1 условную единицу времени.

Примеры различных файлов заданий

Случайное чтение с диска:

$ nano randread.cfg
[readtest]              # называние теста (таких тестов в одном файле может быть несколько)
blocksize=4k            # чтение блоками по 4KB
filename=/dev/sda2      # будем читать раздел sda2
rw=randread             # метод теста - случайное чтение
direct=1                # без буфера
buffered=0              # без кэша
ioengine=libaio         # движок libaio (собственный асинхронный ввод/вывод Linux)
iodepth=32              # тест должен добиться этой глубины очереди

Здесь, по желанию, вы можете изменить: размер блока (blocksize) и читаемый файл (filename). В качестве filename можно указать блочное устройство или обычный файл, но предварительно нужно этот файл создать.

Случайная запись в файл:

$ nano randwrite.cfg
[writetest]
size=1G
blocksize=4k
filename=/tmp/test1
rw=randwrite             # метод теста - случайная запись
direct=1
buffered=0
ioengine=libaio
iodepth=32

В этом примере, по желанию, вы также можете изменить: размер блока (blocksize) и записываемый файл (filename).

Внимание! Когда выполняется тестирование на запись, то в указанный файл (filename) пишутся данные перезатирая его. Поэтому не указывается в качестве filename блочное устройство с нужными данными.

Выполняем тест случайного чтения

Запуск теса:

$ sudo fio randread.cfg

Результат тестирования:

readtest: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=32
fio-3.28
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=162MiB/s][r=41.5k IOPS][eta 00m:00s]
readtest: (groupid=0, jobs=1): err= 0: pid=39490: Thu Oct 20 13:26:00 2022
  read: IOPS=42.5k, BW=166MiB/s (174MB/s)(16.0GiB/98740msec)
    slat (usec): min=4, max=7475, avg=16.52, stdev=13.18
    clat (usec): min=32, max=30637, avg=733.38, stdev=262.41
     lat (usec): min=48, max=30674, avg=750.70, stdev=264.66
    clat percentiles (usec):
     |  1.00th=[  363],  5.00th=[  461], 10.00th=[  506], 20.00th=[  562],
     | 30.00th=[  611], 40.00th=[  660], 50.00th=[  709], 60.00th=[  758],
     | 70.00th=[  816], 80.00th=[  889], 90.00th=[  988], 95.00th=[ 1057],
     | 99.00th=[ 1270], 99.50th=[ 1401], 99.90th=[ 3064], 99.95th=[ 4228],
     | 99.99th=[ 6063]
   bw (  KiB/s): min=113736, max=203504, per=100.00%, avg=170097.57, stdev=16561.25, samples=197
   iops        : min=28434, max=50876, avg=42524.39, stdev=4140.29, samples=197
  lat (usec)   : 50=0.01%, 100=0.03%, 250=0.16%, 500=9.04%, 750=49.04%
  lat (usec)   : 1000=32.94%
  lat (msec)   : 2=8.56%, 4=0.17%, 10=0.05%, 20=0.01%, 50=0.01%
  cpu          : usr=29.34%, sys=69.67%, ctx=7672, majf=0, minf=45
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.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.1%, 64=0.0%, >=64=0.0%
     issued rwts: total=4193536,0,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=32

Run status group 0 (all jobs):
   READ: bw=166MiB/s (174MB/s), 166MiB/s-166MiB/s (174MB/s-174MB/s), io=16.0GiB (17.2GB), run=98740-98740msec

Disk stats (read/write):
  sda: ios=4190107/168, merge=211/117, ticks=771178/93, in_queue=771317, util=100.00%

Разбор отчета по случайному чтению

Первые 4 строки показывают информацию о самом тесте:

readtest: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=32
fio-3.28
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=162MiB/s][r=41.5k IOPS][eta 00m:00s]

Здесь же видим полученную пропускную способность — [r=162MiB/s][r=41.5k IOPS].

Дальше видим более подробную информацию о пройденном тесте:

readtest: (groupid=0, jobs=1): err= 0: pid=39490: Thu Oct 20 13:26:00 2022
  read: IOPS=42.5k, BW=166MiB/s (174MB/s)(16.0GiB/98740msec)
    slat (usec): min=4, max=7475, avg=16.52, stdev=13.18
    clat (usec): min=32, max=30637, avg=733.38, stdev=262.41
     lat (usec): min=48, max=30674, avg=750.70, stdev=264.66
    clat percentiles (usec):
     |  1.00th=[  363],  5.00th=[  461], 10.00th=[  506], 20.00th=[  562],
     | 30.00th=[  611], 40.00th=[  660], 50.00th=[  709], 60.00th=[  758],
     | 70.00th=[  816], 80.00th=[  889], 90.00th=[  988], 95.00th=[ 1057],
     | 99.00th=[ 1270], 99.50th=[ 1401], 99.90th=[ 3064], 99.95th=[ 4228],
     | 99.99th=[ 6063]
   bw (  KiB/s): min=113736, max=203504, per=100.00%, avg=170097.57, stdev=16561.25, samples=197
   iops        : min=28434, max=50876, avg=42524.39, stdev=4140.29, samples=197
  lat (usec)   : 50=0.01%, 100=0.03%, 250=0.16%, 500=9.04%, 750=49.04%
  lat (usec)   : 1000=32.94%
  lat (msec)   : 2=8.56%, 4=0.17%, 10=0.05%, 20=0.01%, 50=0.01%
  cpu          : usr=29.34%, sys=69.67%, ctx=7672, majf=0, minf=45
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.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.1%, 64=0.0%, >=64=0.0%
     issued rwts: total=4193536,0,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=32

Описывать всё не буду, но некоторые вещи объясню.

Здесь показана достигнутая пропускная способность — IOPS=42.5k, BW=166MiB/s, сколько всего было считано с диска и сколько времени на это ушло — (16.0GiB/98740msec).

Также видим минимальную и максимальную латентность: lat (usec): min=48, max=30674.

И есть информация, как изменялся clat по процентилям (clat percentiles (usec)):

  • если взять 1% самых быстрых запросов, то самый медленный из них выполнялся 363 usec — 1.00th=[ 363];
  • если взять 20% самых быстрых запросов, то самый медленный из них выполнялся 562 usec — 20.00th=[ 562] и так далее.

Дальше идёт статистика пропускной способности. Здесь видна минимальная, максимальная и средняя пропускная способность в KiB/s и iops. (bw ( KiB/s): min=113736, max=203504) и (iops : min=28434, max=50876).

А ниже представлена статистика по латентности (lat):

  • число запросов, которые выполнялись 50 usec, было 0,01 % (50=0.01%);
  • число запросов, которые выполнялись 750 usec, было 49,04% (750=49.04%) и так далее.

А ещё ниже показана статистика по использованию ЦПУ:

  • usr — пользовательские процессы;
  • sys — системные процессы;
  • ctx — количество переключения контекста через которые прошел этот поток;
  • majf — количество major page faults. Такие ошибки могут быть устранены только путем доступа к диску;
  • minf — количество minor page fault. Такие ошибки могут быть устранены с помощью страниц, которые уже находятся в памяти.

Выполняем тест случайной записи

Чтобы не затереть свой диск, писать будем в файл. А чтобы было интереснее, в одном файле задания, я опишу сразу два теста: случайную запись блоками 4K и 4M:

$ nano randwrite.cfg

[writetest-4K]
size=1G
blocksize=4k
filename=/tmp/test1
rw=randwrite
direct=1
buffered=0
ioengine=libaio
iodepth=32

[writetest-4M]
size=1G
blocksize=4M
filename=/tmp/test2
rw=randwrite
direct=1
buffered=0
ioengine=libaio
iodepth=32

Запускаем тестирование:

$ sudo fio randwrite.cfg

Разбор отчета по случайной записи блоками 4К

writetest-4K: (groupid=0, jobs=1): err= 0: pid=42936: Sat Oct 22 14:17:41 2022
  write: IOPS=13.3k, BW=52.0MiB/s (54.5MB/s)(1024MiB/19696msec); 0 zone resets
    slat (usec): min=12, max=27704, avg=47.01, stdev=100.91
    clat (usec): min=2, max=115525, avg=2352.97, stdev=3452.47
     lat (usec): min=70, max=115567, avg=2400.94, stdev=3455.61
    clat percentiles (usec):
     |  1.00th=[    97],  5.00th=[   322], 10.00th=[  1074], 20.00th=[  1418],
     | 30.00th=[  1500], 40.00th=[  1582], 50.00th=[  1663], 60.00th=[  1762],
     | 70.00th=[  1909], 80.00th=[  2409], 90.00th=[  4752], 95.00th=[  6521],
     | 99.00th=[  9372], 99.50th=[ 11076], 99.90th=[ 65799], 99.95th=[ 81265],
     | 99.99th=[104334]
   bw (  KiB/s): min= 1548, max=81288, per=50.25%, avg=53508.18, stdev=22017.15, samples=39
   iops        : min=  387, max=20322, avg=13376.90, stdev=5504.33, samples=39
  lat (usec)   : 4=0.01%, 50=0.01%, 100=1.07%, 250=2.89%, 500=2.50%
  lat (usec)   : 750=1.39%, 1000=1.45%
  lat (msec)   : 2=63.60%, 4=14.35%, 10=12.01%, 20=0.44%, 50=0.17%
  lat (msec)   : 100=0.10%, 250=0.02%
  cpu          : usr=7.34%, sys=48.00%, ctx=197078, majf=0, minf=14
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.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.1%, 64=0.0%, >=64=0.0%
     issued rwts: total=0,262144,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=32

Здесь мы достигли скорость = IOPS=13.3k, BW=52.0MiB/s.

Латентность min=70 usec, max=115567 usec. И больше всего времени (63.60%) латентность была — 2 msec.

Разбор отчета по случайной записи блоками 4M

writetest-4M: (groupid=0, jobs=1): err= 0: pid=42937: Sat Oct 22 14:17:41 2022
  write: IOPS=339, BW=1358MiB/s (1424MB/s)(1024MiB/754msec); 0 zone resets
    slat (usec): min=172, max=10518, avg=544.27, stdev=871.18
    clat (msec): min=14, max=181, avg=92.03, stdev=33.74
     lat (msec): min=22, max=181, avg=92.58, stdev=33.58
    clat percentiles (msec):
     |  1.00th=[   25],  5.00th=[   28], 10.00th=[   32], 20.00th=[   67],
     | 30.00th=[   84], 40.00th=[   91], 50.00th=[   97], 60.00th=[  103],
     | 70.00th=[  110], 80.00th=[  115], 90.00th=[  126], 95.00th=[  142],
     | 99.00th=[  182], 99.50th=[  182], 99.90th=[  182], 99.95th=[  182],
     | 99.99th=[  182]
   bw (  MiB/s): min= 1333, max= 1333, per=100.00%, avg=1333.33, stdev= 0.00, samples=1
   iops        : min=  333, max=  333, avg=333.00, stdev= 0.00, samples=1
  lat (msec)   : 20=0.39%, 50=14.45%, 100=40.62%, 250=44.53%
  cpu          : usr=5.31%, sys=13.28%, ctx=229, majf=0, minf=10
  IO depths    : 1=0.4%, 2=0.8%, 4=1.6%, 8=3.1%, 16=6.2%, 32=87.9%, >=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=99.6%, 8=0.0%, 16=0.0%, 32=0.4%, 64=0.0%, >=64=0.0%
     issued rwts: total=0,256,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=32

Здесь мы достигли скорость = IOPS=339, BW=1358MiB/s.

Латентность min=22 msec, max=181 msec. И больше всего времени латентность была: 44.53 %250 msec, и 40.62%100 msec.

Итог

Нами была рассмотрена утилита fio, которая используется для тестирования дисковой подсистемы. Мы разобрали: как писать файлы заданий для этой утилиты и как читать отчеты о проделанных тестах.

Сводка
Утилита fio
Имя статьи
Утилита fio
Описание
Утилита fio предназначена для выполнения нагрузочного тестирования дисковой подсистемы. При этом тесты могут быть достаточно разнообразны

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

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