Я понимаю глубину очереди, которая представляет собой количество невыполненных запросов ввода-вывода, которые может обработать контроллер хранилища (https://www.tomshardware.com/reviews/ssd-gaming-performance,2991-3.html) то есть это ограничение на контроллер хранилища, который обрабатывает запросы ввода-вывода и отправляет команды на диск (r / w) и (не строго?) отбрасывает запросы, если их больше, чем он может обработать (что будут повторно представлены клиентами предположительно).
Причиной большого количества запросов ввода-вывода может быть несколько клиентских подключений, запрашивающих ввод-вывод, или несколько процессов даже с одного хоста, запрашивающего ввод-вывод (что я думал, но, похоже, ОС использует планировщик ввода-вывода, объединяет ввод-вывод). Запросы O - которые исходят из буфера при выполнении периодической синхронизации или синхронизации по запросу и отправляют только фиксированное количество устаревших запросов, чтобы не перегружать устройства хранения?)
Теперь перейдем к определению iodepth на странице руководства fio:
Количество модулей ввода-вывода, которые нужно держать в движении для файла. Обратите внимание, что увеличение iodepth выше 1 не повлияет на синхронные ioengine (за исключением малых степеней, когда используется verify_async).
Это согласуется с моим пониманием глубины очереди. Если ввод-вывод синхронный (блокирующий ввод-вывод), у нас может быть только одна очередь.
Даже асинхронные механизмы могут налагать ограничения ОС, в результате чего желаемая глубина не может быть достигнута. Это может произойти в Linux при использовании libaio без установки direct = 1, поскольку буферизованный ввод-вывод не является асинхронным в этой ОС.
Смущает все это утверждение.
Следите за распределением глубины ввода / вывода в выводе fio, чтобы убедиться, что достигнутая глубина соответствует ожиданиям. По умолчанию: 1.
Я провел несколько тестов для каждого iodepth и типа устройства с 22 параллельными заданиями, поскольку количество ЦП равно 24, и с rwtype: последовательное чтение и последовательная запись. Iodepth составляет 1,16,256,1024,32768 (я знаю, что 32 или 64 должны быть максимальным пределом, я все равно хотел попробовать).
И результаты практически одинаковы для всех глубин и для всех дисков (RAID 6 SSD, NVME и NFS): за исключением последовательного чтения на диске NVME с глубиной 32768.
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=99.9%
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%
Для NVME с глубиной 32768,
complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=100.0%
Я использовал движок libaio в fio (потому что я не уверен, какой движок ввода-вывода мне нужен для тестирования асинхронного ввода-вывода, и libaio, по-видимому, правильный. Это совсем другой вопрос)
Так что же происходит? Почему в поле "Отправить и завершить" отображается 1-4 (за исключением одного запуска NVME, где оно> 64)
[global]
lockfile=none
kb_base=1024
fallocate=posix
blocksize=64k
openfiles=100
ioengine=libaio
buffered=1
invalidate=1
loops=5
randrepeat=1
size=512M
numjobs=22
[sr-iodepth-1]
description="Sequential Write,Parallel jobs-22,IO depth-1,libaio"
readwrite=write
size=5G
iodepth=1
[sr-iodepth-16]
description="Sequential Write,Parallel jobs-22,IO depth-16,libaio"
readwrite=write
size=5G
iodepth=16
[sr-iodepth-256]
description="Sequential Write,Parallel jobs-22,IO depth-256,libaio"
readwrite=write
size=5G
iodepth=256
[sr-iodepth-1024]
description="Sequential Write,Parallel jobs-22,IO depth-1024,libaio"
readwrite=write
size=5G
iodepth=1024
[sr-iodepth-32768]
description="Sequential Write,Parallel jobs-22,IO depth-32768,libaio"
readwrite=write
size=5G
iodepth=32768
[sw-iodepth-1]
description="Sequential Read,Parallel jobs-22,IO depth-1,libaio"
readwrite=read
size=512M
iodepth=1
[sw-iodepth-16]
description="Sequential Read,Parallel jobs-22,IO depth-16,libaio"
readwrite=read
size=512M
iodepth=16
[sw-iodepth-256]
description="Sequential Read,Parallel jobs-22,IO depth-256,libaio"
readwrite=read
size=512M
iodepth=256
[sw-iodepth-1024]
description="Sequential Read,Parallel jobs-22,IO depth-1024,libaio"
readwrite=read
size=512M
iodepth=1024
[sw-iodepth-32768]
description="Sequential Read,Parallel jobs-22,IO depth-32768,libaio"
readwrite=read
size=512M
iodepth=32768
(Пожалуйста, не задавайте несколько вопросов в одном посте - это заставляет отвечать действительно трудно...)
глубина очереди, которая представляет собой количество невыполненных запросов ввода-вывода [...], которая обрабатывает запросы ввода-вывода и отправляет команды на диск (r / w) и (не строго?) отбрасывает запросы
Чрезмерные запросы обычно не отбрасываются - их просто некуда ставить в очередь на устройстве, поэтому что-то еще (например, ОС) должно удерживать их и отправлять их, когда пространство доступно. Они не потеряны, их просто не принимают.
И причина большого количества запросов ввода-вывода
Причин много - вы перечислили одну из них. Например, устройство могло просто работать медленно (вспомните SD-карту старого образца) и не успевать даже за одним «клиентом».
только фиксированное количество устаревших [sic] запросов, чтобы не перегружать устройства хранения?)
Это цель, но ничто не говорит о том, что устройство сможет работать (и иногда есть причины / конфигурации, по которым слияние не происходит).
Даже асинхронные механизмы могут налагать ограничения ОС, в результате чего желаемая глубина не может быть достигнута. Это может произойти в Linux при использовании libaio без установки direct = 1, поскольку буферизованный ввод-вывод не является асинхронным в этой ОС.
Смущает все это утверждение.
Причуда Linux в том, чтоO_DIRECT
Ввод-вывод (по умолчанию) проходит через буферный кеш (это так называемый буферизованный ввод-вывод). Из-за этого, даже если вы думаете, что отправили асинхронно (с помощью Linux AIO), на самом деле вы просто получаете синхронное поведение. Видеть https://github.com/axboe/fio/issues/512#issuecomment-356604533 для объяснения, сформулированного иначе.
Почему нужно отправить и завершить шоу 1–4
В вашей конфигурации это:
buffered=1
Вы не прислушались к предупреждению, о котором думали ранее! buffered=1
это то же самое, что сказать direct=0
. Даже если бы у тебя был direct=1
, по умолчанию fio
отправляет операции ввода-вывода по одному, поэтому, если ваше устройство настолько быстрое, что оно завершило ввод-вывод до того, как следующее будет поставлено в очередь, вы можете не увидеть глубину выше единицы. Если вы хотите принудительно / гарантировать пакетную отправку, см. iodepth_batch_*
варианты, упомянутые в fio
HOWTO / руководство.
ОК, возвращаясь к вопросам в заголовке:
Что на самом деле означает iodepth в тестах fio?
Это максимальное количество невыполненных операций ввода-вывода, fio
воля попытаться встать в очередь внутри (но обратите внимание, что fio
может никогда не достичь его по причинам, указанным выше и ниже).
Это [iodepth] глубина очереди?
Может быть, и дальше это также зависит от того, что вы подразумеваете под «глубиной очереди». Если вы имеете в виду avgqu-sz
как сообщает такой инструмент, как Linux iostat
затем iodepth
может быть похожими или сильно отличаться в зависимости от таких вещей, как используемый ioengine, параметры, используемые с этим механизмом ввода-вывода, тип и стиль отправляемого ввода-вывода, уровни, которые он должен пройти, пока не достигнет уровня сообщил и т. д.
Я думаю, вы задавали варианты этих вопросов в довольно многих разных местах - например, в В списке рассылки fio есть ответы на некоторые из вышеперечисленных - и в ЭТОМ письме упоминается, что вы также писали на https://unix.stackexchange.com/questions/459045/what-exactly-is-iodepth-in-fio . Возможно, вы захотите позаботиться, потому что вы потенциально заставляете людей давать ответы на вопросы, на которые уже были даны ответы в другом месте, и вы не связываете их вместе, что затрудняет обнаружение повторяющихся ответов ...
Из https://tobert.github.io/post/2014-04-17-fio-output-explained.html
submit и complete представляют количество отправленных IO за раз по fio и количество завершенных за раз. В случае теста на порог, используемого для генерации этого вывода, iodepth имеет значение по умолчанию 1, поэтому 100% операций ввода-вывода были отправлены по одному за раз, помещая результаты в сегмент 1–4. В основном это имеет значение, только если iodepth больше 1.
Это означает, что первая строка показывает количество невыполненных операций ввода-вывода, которые у вас были в любой момент времени, и это соответствует определенному вами iodepth.
Строка отправки показывает, сколько операций ввода-вывода было отправлено каждый раз, когда была отправка, и, по сути, показывает, что операции ввода-вывода были отправлены по 4 за раз, а полная строка показывает, что 4 ввода-вывода были возвращены в каждом цикле опроса, поэтому fio также отправил 4 ввода-вывода взамен. .
В общем, глубина io и глубина очереди одинаковы. Это количество операций ввода-вывода, которые устройство / контроллер может обрабатывать одновременно, остальные операции ввода-вывода будут ожидающими в очереди на уровне ОС / приложения.
Вы используете низкую глубину очереди для снижения задержек и более высокую глубину очереди для повышения пропускной способности. Устройство использует глубину очереди либо для внутреннего параллелизма (SSD), либо для переупорядочения и слияния связанных IO (HDD и SSD).