Я копирую большие файлы (3 x 30 Гбайт) между двумя файловыми системами на сервере Linux (ядро 2.6.37, 16 ядер, 32 Гбайт ОЗУ), и у меня низкая производительность. Я подозреваю, что использование буферного кеша убивает производительность ввода-вывода.
Чтобы попытаться сузить проблему, я использовал fio непосредственно на диске SAS для мониторинга производительности.
Вот результат 2 запусков fio (первый с direct = 1, второй direct = 0):
Конфиг:
[test]
rw=write
blocksize=32k
size=20G
filename=/dev/sda
# direct=1
Запуск 1:
test: (g=0): rw=write, bs=32K-32K/32K-32K, ioengine=sync, iodepth=1
Starting 1 process
Jobs: 1 (f=1): [W] [100.0% done] [0K/205M /s] [0/6K iops] [eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=4667
write: io=20,480MB, bw=199MB/s, iops=6,381, runt=102698msec
clat (usec): min=104, max=13,388, avg=152.06, stdev=72.43
bw (KB/s) : min=192448, max=213824, per=100.01%, avg=204232.82, stdev=4084.67
cpu : usr=3.37%, sys=16.55%, ctx=655410, majf=0, minf=29
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 r/w: total=0/655360, short=0/0
lat (usec): 250=99.50%, 500=0.45%, 750=0.01%, 1000=0.01%
lat (msec): 2=0.01%, 4=0.02%, 10=0.01%, 20=0.01%
Run status group 0 (all jobs):
WRITE: io=20,480MB, aggrb=199MB/s, minb=204MB/s, maxb=204MB/s, mint=102698msec, maxt=102698msec
Disk stats (read/write):
sda: ios=0/655238, merge=0/0, ticks=0/79552, in_queue=78640, util=76.55%
Запуск 2:
test: (g=0): rw=write, bs=32K-32K/32K-32K, ioengine=sync, iodepth=1
Starting 1 process
Jobs: 1 (f=1): [W] [100.0% done] [0K/0K /s] [0/0 iops] [eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=4733
write: io=20,480MB, bw=91,265KB/s, iops=2,852, runt=229786msec
clat (usec): min=16, max=127K, avg=349.53, stdev=4694.98
bw (KB/s) : min=56013, max=1390016, per=101.47%, avg=92607.31, stdev=167453.17
cpu : usr=0.41%, sys=6.93%, ctx=21128, majf=0, minf=33
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 r/w: total=0/655360, short=0/0
lat (usec): 20=5.53%, 50=93.89%, 100=0.02%, 250=0.01%, 500=0.01%
lat (msec): 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.12%
lat (msec): 100=0.38%, 250=0.04%
Run status group 0 (all jobs):
WRITE: io=20,480MB, aggrb=91,265KB/s, minb=93,455KB/s, maxb=93,455KB/s, mint=229786msec, maxt=229786msec
Disk stats (read/write):
sda: ios=8/79811, merge=7/7721388, ticks=9/32418456, in_queue=32471983, util=98.98%
Я недостаточно разбираюсь в fio, чтобы интерпретировать результаты, но я не ожидаю, что общая производительность с использованием буферного кеша будет на 50% меньше, чем с O_DIRECT.
Может ли кто-нибудь помочь мне интерпретировать вывод fio?
Есть ли какие-нибудь настройки ядра, которые могут исправить / минимизировать проблему?
Большое спасибо,
С помощью O_DIRECT ядро обходит все обычные механизмы кэширования и записывает непосредственно на диск. Поскольку вы не используете O_SYNC, если кэширование включено (без использования O_DIRECT), тогда ядро может солгать вам, что «да, да, я написал это, не волнуйтесь!», Даже если это не так. запишите его на диск, он был записан только в какой-то кеш (кеш диска / кеш страницы / ...).
Переход напрямую означает, что вы не тратите время на копирование, поэтому прямой ввод-вывод может выполняться быстрее, но результаты действительно выглядят странно, поскольку разброс времени завершения второго запуска намного больше, чем у первого запуска. Также сравните статистику диска:
sda: ios=0/655238, merge=0/0, ticks=0/79552, in_queue=78640, util=76.55%
против
sda: ios=8/79811, merge=7/7721388, ticks=9/32418456, in_queue=32471983, util=98.98%
Первый прогон не производил слияния (слияние =) операций ввода-вывода, второй -. Во время первого запуска диск не был полностью занят (util =), а во втором запуске он был очень занят. В in_queue
время второго запуска также выше, что свидетельствует о резервном копировании операций ввода-вывода в ядре. Странно - возможно, обратная запись была как-то нарушена? Вы можете решить эту проблему, изменив планировщик ввода-вывода на noop
или deadline
но выглядит глючно ...