Сервер в кармане, или просто о сложном!

главная - Статьи - Linux, FreeBSD

Нагрузка на диски в Linux

Теги: Система Linux Настройка сервера

Для измерения текущей нагрузки на диски (что происходит, кто куда копирует и прочее) в Linux можно использовать iotop (и здесь же lsof) и iostat. А для тестирования возможностей дисковой системы fio. Несмотря на то, что первое, о чем можно подумать в плане попугаев - это IOPS или же Мб/сек за чтение или запись, обратите внимание на время ожидания. Примерно как если бы вы стояли в очереди в кассу: вас обслужили бы за 2 минуты, но очередь может быть минут на 30. И со стороны наблюдателя ваш процесс обслуживания будет "висеть". Именно так могут ощущать себя клиенты сервера, если время ожидания будет намного превышать время выполнения конкретной задачи. Поэтому определение длинной очереди и задержек часто бывает более важным, чем знать, что ваш диск "вау, может писать 400 Мбит/с". Нагрузка на диск может оказаться в 4000 Мбит/с в течение длительных периодов времени и все это время клиенты сервера будут недовольны.

Я здесь пишу свой опыт, со своим видением и трактовкой. Пожалуйста, учитывайте это.

IOTOP

Посмотреть, какие процессы в настоящее время создают нагрузку на диск удобно смотреть командой iotop:

# iotop
Total DISK READ: 38.27 M/s | Total DISK WRITE: 36.91 M/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
28096 be/4 root        0.00 B/s   15.75 K/s  0.00 % 99.99 % [flush-8:64]
28044 be/3 root        0.00 B/s    0.00 B/s  0.00 % 99.99 % [jbd2/sde1-8]
28074 be/4 root       38.14 M/s   38.12 M/s  0.00 % 94.27 % mc -P /tmp/mc-root/mc.pwd.27971
    1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % init
    2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
    3 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [migration/0]
    4 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/0]
    5 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [stopper/0]
    6 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [watchdog/0]
    7 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [migration/1]
...

Здесь видно, что в данный момент mc что-то пишет (а в это время в другом окне я в самом деле копировал кучу файлов на usb-диск в Midnight Commander (он же mc).

Понять, что коипрует mc в данный момент можно узнать командой:

# lsof | grep mc

IOSTAT

Пример вывода iostat на незагруженной в данный момент старенькой системе из двух SATA HDD в soft raid 1 (зеркало) mdadm:

10/02/2015 12:30:58 PM
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.22    0.00    1.91    8.23    0.00   84.64

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     0.00   40.20    1.80     0.39     0.00    19.24     0.21    4.90   4.51  18.94
sdb               0.00     0.00    0.00    1.80     0.00     0.00     3.67     0.01    7.22   7.11   1.28
md1               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
md2               0.00     0.00   40.20    0.40     0.39     0.00    19.82     0.00    0.00   0.00   0.00
md0               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

Команда выглядела так:

iostat -x -t -m 5

-x - расширенная статистика

-t - выводить время для каждой порции замеров

-m - результаты в Мбайт

5 - интервал замеров 5 секунд.

Если нужны не история, а динамика процесса, попробуйте так:

watch iostat -x -t -m 1 2

В этом выводе r/s и w/s это отправленные к устройству запросы на выполнение (IOPS, которые хотелось бы, чтобы устройство выполнило).

await - время, включающее ожидание выполнения запроса (как если бы вы встали в очередь в кассу и ждали бы, пока вас обслужат).

svctm - время, реально затраченное на выполнение запроса (время "на самой кассе").

Для обычных SATA дисков нагрузка IOPS где-то до 100-130 вполне выполнимая.  В момент проведения замеров запрошенная нагрузка была 40 IOPS, поэтому запрос практически в очереди и не стоял, его обслужили почти сразу (на "кассе" никого не было). Поэтому await практически равен svctm.

Другое дело, когда нагрузка на диск вырастает:

10/02/2015 12:33:21 PM
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          10.36    0.00   10.26   52.41    0.00   26.97

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               2.80  3800.40   65.20  327.80     5.97    16.12   115.07    45.79  116.45   2.38  93.38
sdb               0.20  3799.00   18.80  329.00     2.41    16.12   109.09    35.00  100.60   2.08  72.28
md1               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
md2               0.00     0.00   87.00 4124.80     8.38    16.11    11.91     0.00    0.00   0.00   0.00
md0               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

%iowait - простой процессора (время в процентах) от или процессоров, в то время пока обрабатывались запросы. Т.е. в среднем процессор отдыхал почти 50% времени.

%user - загруженность процессора пользовательскими приложениями. По этому параметру видно, например, что в данный период процессор был почти не занят. Это важно, т.к. может помочь отсечь подозрения в тормозах из-за процессора.

Замер сделан во время переноса большого количества писем из одной папки IMAP в другую. Особо обратите внимание на await и svctm. Налицо длинная очередь (отношение await к svctm). Дисковая система (или чипсет, или медленный контроллер SATA, или...) не справляется с запрошенной нагрузкой (w/s).. Для пользователей в этот момент все выглядело просто - сервер тупит или даже завис.

FIO

Заранее проверить производительность дисков можно с помощью fio. Также можно примерно оценить на одной машине производительность дисков и понимать, какой уровень "в среднем по больнице" вы можете ожидать. Это, конечно же, не правильно, но оценить все же поможет. Глубже анализировать результаты, а, главное, методики тестов мне пока трудно.

CentOS:

# yum install fio

Ubuntu:

# apt-get install fio

В общем виде запуск выглядит так:

# fio your.cfg

Файл your.cfg (название произвольное) может быть примерно таким (пример рабочего конфига для теста на чтение):

[readtest]
blocksize=4k
filename=/dev/sda
rw=randread
direct=1
buffered=0
ioengine=libaio
iodepth=32

Буферизацию не используем (buffered=0), чтение не последовательное (rw=randread).

Во время выполнения этого теста (а выполняться тест может доооолго, надоест - Ctrl+C, результаты все равно будут) можно запустить iostat и посмотреть, что происходит:

10/02/2015 04:17:37 PM
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.60    0.00    1.70    4.01    0.00   93.69

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     2.80  110.20    1.00     0.43     0.01     8.19    32.23  289.11  289.45  251.20   8.99 100.00
sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00

Обратите внимание на отношение await к svctm: await/svctm = 32,11..11, т.е. можно считать 32. Это и есть iodepth из конфига your.cfg. Теперь проще понять смысл iodepth - мы указываем, насколько хотим в тесте имитировать длинную очередь заданий.

Я не стал ждать два дня, Ctrl+C и вот результат:

readtest: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=32
fio-2.1.3
Starting 1 process
^Cbs: 1 (f=1): [r] [2.5% done] [439KB/0KB/0KB /s] [109/0/0 iops] [eta 02d:00h:19m:31s]
fio: terminating on signal 2

readtest: (groupid=0, jobs=1): err= 0: pid=4307: Fri Oct  2 17:15:17 2015
  read : io=1920.9MB, bw=448449B/s, iops=109, runt=4491370msec
    slat (usec): min=5, max=599, avg=49.93, stdev= 8.69
    clat (msec): min=10, max=1445, avg=292.21, stdev=208.52
     lat (msec): min=10, max=1445, avg=292.26, stdev=208.52
    clat percentiles (msec):
     |  1.00th=[   34],  5.00th=[   49], 10.00th=[   67], 20.00th=[  102],
     | 30.00th=[  141], 40.00th=[  186], 50.00th=[  241], 60.00th=[  306],
     | 70.00th=[  383], 80.00th=[  478], 90.00th=[  603], 95.00th=[  693],
     | 99.00th=[  865], 99.50th=[  930], 99.90th=[ 1057], 99.95th=[ 1106],
     | 99.99th=[ 1221]
    bw (KB  /s): min=  242, max=  527, per=100.00%, avg=438.05, stdev=25.81
    lat (msec) : 20=0.01%, 50=5.48%, 100=14.13%, 250=32.05%, 500=30.56%
    lat (msec) : 750=14.65%, 1000=2.93%, 2000=0.21%
  cpu          : usr=0.54%, sys=1.14%, ctx=501271, majf=0, minf=59
  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    : total=r=491736/w=0/d=0, short=r=0/w=0/d=0

Run status group 0 (all jobs):
   READ: io=1920.9MB, aggrb=437KB/s, minb=437KB/s, maxb=437KB/s, mint=4491370msec, maxt=4491370msec

Disk stats (read/write):
  sda: ios=491810/3605, merge=257/4862, ticks=143668620/1157164, in_queue=144830660, util=100.00%

Получили 109 iops, что в принципе нормально, диск обычный, SATA.

11.02.2017 10:26 4mg
Спасибо. Кратко и понятно. Только пожалуйста, сделайте авторизацию удобнее - кучу шагов надо сделать, чтобы оставить комментарий.

Авторизуйтесь для добавления комментариев!


    забыли пароль?    новый пользователь?