Назад | Перейти на главную страницу

Почему io scheduler не объединяет запросы?

Через некоторое время (или количество записанных данных) после перезагрузки сервера скорость записи упадет до менее 1 МБ / с. Это независимо от того, какая файловая система (также необработанный раздел) и независимо от жесткого диска (HW RAID) или SSD (SW RAID с SSD, подключенным к портам AHCI материнской платы, а не к рейдовой плате). Мы тестируем с командой dd if=/dev/zero of=tst bs=1M oflag=dsync (Я также пробовал 1k а также без dsync, но производительность была не лучше).

Единственное, что я заметил, это то, что avgrq-sz всего 8 в выводе iostat (на других протестированных серверах было больше 600) и что req / s составляет около 100 (также на SSD). Больше бега dd параллельно дал каждому из них по 1 МБ / с и каждому из них около 100 запросов / с.

Образец iostat -xN 1 вывод:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdc               0.00     0.00    0.00  125.00     0.00   500.00     8.00     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     0.00    0.00  124.00     0.00   496.00     8.00     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     3.00    0.00  128.00     0.00   524.00     8.19     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     6.00    0.00  124.00     0.00   728.00    11.74     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     0.00    0.00  125.00     0.00   500.00     8.00     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     3.00    0.00  128.00     0.00   524.00     8.19     0.00    0.00    0.00    0.00   0.00   0.00

Выход Iostat с 8x dd Бег:

sdc               0.00    64.00    0.00  959.00     0.00  7560.00    15.77     0.00    0.00    0.00    0.00   0.00   0.00

lsblk -O вывод согласуется с другими серверами, у которых нет этой проблемы (например, MIN-IO, RQ-SIZE, LOG-SEC). Текущее ядро ​​4.9.16-gentoo, но проблема началась с более старым ядром. Бег dd с участием oflag=direct быстро.

РЕДАКТИРОВАТЬ: Основываясь на ответе shodanshok, я теперь вижу, что запросы действительно маленькие, но вопрос в том, почему планировщик io не объединяет их в более крупные запросы? Я пробовал оба cfq и deadline планировщики. Могу ли я что-нибудь проверить (или сравнить с другими серверами)?

Вывод при работе с oflag=direct (скорость нормальная):

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdc               0.00     0.00    2.00  649.00     8.00 141312.00   434.16     2.78    4.26    2.00    4.27   1.53  99.60
sdc               0.00     0.00    0.00  681.00     0.00 143088.00   420.23     2.71    3.99    0.00    3.99   1.46  99.20
sdc               0.00     0.00    2.00  693.00     8.00 146160.00   420.63     2.58    3.71    0.00    3.72   1.42  98.80
sdc               0.00    49.00    2.00  710.00     8.00 146928.00   412.74     2.68    3.76   22.00    3.71   1.39  99.20
sdc               0.00     0.00    1.00  642.00     4.00 136696.00   425.19     2.43    3.79   60.00    3.71   1.42  91.60

Сервер - это Dell PowerEdge R330 с 32 ГБ ОЗУ, контроллер LSI MegaRAID 3108 с жесткими дисками, твердотельные накопители, подключенные к встроенному SATA, процессор Intel E3-1270. Файловая система ext3, но то же самое происходит с dd в необработанный раздел.

Выход lsblk (sdc - это HW RAID HDD, sda / sdb SW RAID SSD):

NAME    MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sdb       8:16   0 223.6G  0 disk
|-sdb4    8:20   0     1K  0 part
|-sdb2    8:18   0   140G  0 part
| `-md1   9:1    0   140G  0 raid1 /
|-sdb5    8:21   0    25G  0 part
| `-md2   9:2    0    25G  0 raid1 /var/log
|-sdb3    8:19   0     1G  0 part
|-sdb1    8:17   0    70M  0 part
| `-md0   9:0    0    70M  0 raid1 /boot
`-sdb6    8:22   0  57.5G  0 part
  `-md3   9:3    0  57.5G  0 raid1 /tmp
sr0      11:0    1  1024M  0 rom
sdc       8:32   0   3.7T  0 disk
`-sdc1    8:33   0   3.7T  0 part  /home
sda       8:0    0 223.6G  0 disk
|-sda4    8:4    0     1K  0 part
|-sda2    8:2    0   140G  0 part
| `-md1   9:1    0   140G  0 raid1 /
|-sda5    8:5    0    25G  0 part
| `-md2   9:2    0    25G  0 raid1 /var/log
|-sda3    8:3    0     1G  0 part
|-sda1    8:1    0    70M  0 part
| `-md0   9:0    0    70M  0 raid1 /boot
`-sda6    8:6    0  57.5G  0 part
  `-md3   9:3    0  57.5G  0 raid1 /tmp

С участием oflag=direct скорость нормальная, но проблема в том, что приложения не используют прямой io, поэтому даже простой cp медленный.

/sys/block/sdc/queue/hw_sector_size : 512
/sys/block/sdc/queue/max_segment_size : 65536
/sys/block/sdc/queue/physical_block_size : 512
/sys/block/sdc/queue/discard_max_bytes : 0
/sys/block/sdc/queue/rotational : 1
/sys/block/sdc/queue/iosched/fifo_batch : 16
/sys/block/sdc/queue/iosched/read_expire : 500
/sys/block/sdc/queue/iosched/writes_starved : 2
/sys/block/sdc/queue/iosched/write_expire : 5000
/sys/block/sdc/queue/iosched/front_merges : 1
/sys/block/sdc/queue/write_same_max_bytes : 0
/sys/block/sdc/queue/max_sectors_kb : 256
/sys/block/sdc/queue/discard_zeroes_data : 0
/sys/block/sdc/queue/read_ahead_kb : 128
/sys/block/sdc/queue/discard_max_hw_bytes : 0
/sys/block/sdc/queue/nomerges : 0
/sys/block/sdc/queue/max_segments : 64
/sys/block/sdc/queue/rq_affinity : 1
/sys/block/sdc/queue/iostats : 1
/sys/block/sdc/queue/dax : 0
/sys/block/sdc/queue/minimum_io_size : 512
/sys/block/sdc/queue/io_poll : 0
/sys/block/sdc/queue/max_hw_sectors_kb : 256
/sys/block/sdc/queue/add_random : 1
/sys/block/sdc/queue/optimal_io_size : 0
/sys/block/sdc/queue/nr_requests : 128
/sys/block/sdc/queue/scheduler : noop [deadline] cfq
/sys/block/sdc/queue/discard_granularity : 0
/sys/block/sdc/queue/logical_block_size : 512
/sys/block/sdc/queue/max_integrity_segments : 0
/sys/block/sdc/queue/write_cache : write through

Размер запроса (avgrq-sz) маленький, потому что ты являются выдача небольших запросов на запись. Ваш dd Команда, хотя и указав размер блока 1 МБ, попадает в кэш страниц, и поэтому каждый запрос на 1 МБ действительно представляет собой набор запросов размером 256 * 4 КБ. Это отражено в avgrq-sz которые, будучи выражены в единицах размером 512 байт, идеально совпадают с записью страницы размером 4 КБ. Более того, даже SSD может иметь плохую производительность при синхронизированной записи, как того требует oflag=dsync. Тем не менее, обратите внимание, что планировщик ввода-вывода следует объединить эти небольшие запросы размером 4 КБ с более крупными, но этого не происходит.

Что нужно проверить:

  • что вы видите издает cat /sys/block/sdc/queue/scheduler? Если noop выбранный планировщик, попробуйте выбрать deadline
  • твой /sys/block/sdc/queue/max_sectors_kb хотя бы 1024?
  • попробуйте выполнить dd if=/dev/zero of=tst bs=1M oflag=direct: Производительность ввода-вывода должна быть намного выше, не так ли?