Отказ от ответственности. Эта часть тестов предназначена для описания общей идеологии тестирования. Результаты и методология могут быть неправильными и показывать некорректный, или неприменимый в вашем случае, результат.
Базовые скорости, от которых я буду отталкиваться, сформированы как результат не очень показательных тестов из статей:
Тестирование локальных дисков и систем хранения данных: подводные камни. Часть 1 - общая
Тестирование локальных дисков и систем хранения данных: подводные камни. Часть 2 - виртуализация
Тестирование локальных дисков и систем хранения данных: подводные камни. Часть 3 – цифры и предварительные итоги
Тестирование локальных дисков и систем хранения данных: подводные камни. Часть 4 – что там изнутри виртуализации
Новый ноутбук: скорость, плюсы-минусы, DiskSPD, Hyper-V и продолжение про методику тестирование скорости
Новый ноутбук 2: скорость, плюсы-минусы, DiskSPD, Hyper-V и далее
Итак, тесты.
Тест скорости локальных дисков сформирован исходя из того, что у меня на ноутбуке 64 Гб памяти, 6 ядер и 12 потоков. И это AMD, который показывает на AMD варианте HT хороший прирост скорости вплоть до использования всех 12 потоков при дисковых операциях.
Поэтому тесты планировались следующие: (потом все поменялось)
Для Windows:
diskSPD для 8 и 12 потоков на одном 150 Гб файле, с файловой системой NTFS, размер кластера 4к.
diskSPD для 8 и 12 потоков на одном 150 Гб файле, с файловой системой NTFS, размер кластера 8к.
Тесты на 5 минут: тест 1 - 100% чтение, тест 2 - 100% записи. IO блок 4k
Итого 8 тестов.
Для Windows server внутри Hyper-V:
Виртуальной машине будет выделено 8 ядер и 24 Гб памяти. Очередь 16.
diskSPD для 8 потоков на одном 150 Гб файле, с файловой системой NTFS, размер кластера внутри VM 4к, параметры vhdx диска LogicalSectorSize 4KB PhysicalSectorSizeByte 4K
diskSPD для 8 потоков на одном 200 Гб файле, с файловой системой NTFS, размер кластера 4к внутри VM, параметры vhdx диска LogicalSectorSize 4KB PhysicalSectorSizeByte 4K, NTFS диска с файлом VM с размером кластера 8k.
Полученные данные надо было бы сводить в таблицу, но тогда будет картинка, а это неудобно, поэтому:
тестовый прогон, когда я ошибся с параметром очереди:
В IOPS per thread указан разброс, с округлением вниз, до целых тысяч.
Короткие тесты хоста (d10 = 10 секунд на тест), в данном случае моего ноутбука.
Новый стенд я так и не собрал, а на основных тестовых стендах крутятся совсем другие задачи.
Расшифровка параметров: diskspd Command line and parameters
-t8 -w0 -b4k -W10 -o2 -d10 -Suw -D –L
-t8 -t<count> Number of threads per target.
-w0 -w<percentage> Percentage of write requests to issue (default = 0, 100% read).
-b4k -b Block size in bytes or KiB, MiB, or GiB (default = 64K).
-W<seconds> Warmup time – duration of the test before measurements start
-o2 -o<count> Number of outstanding I/O requests per-target per-thread.
-d10 -d<seconds> Duration of measurement period in seconds, not including cool-down or warm-up time (default = 10 seconds).
-Suw -S[bhmruw] This flag modifies the caching and write-through modes for the test target.
-Su Disable software caching, for unbuffered I/O.
-Sw Enable write-through I/O. This opens the target with the FILE_FLAG_WRITE_THROUGH flag. This can be combined with either buffered (-Sw or -Sbw) or unbuffered I/O (-Suw).
-D<milliseconds> Capture IOPs higher-order statistics in intervals of <milliseconds>
-L Measure latency statistics.
-c<size> В пример не попало.
Короткие тесты хоста NTFS 4k
-t8 -w0 -b4k -W10 -o2 -d10 -Suw -D -L = 42-44 k IOPS per thread = 347 k IOPS total
-t12 -w0 -b4k -W10 -o2 -d10 -Suw -D -L = 36-36 k IOPS per thread = 453 k IOPS total
-t8 -w100 -b4k -W10 -o2 -d10 -Suw -D -L = 33-34 k IOPS per thread = 272 k IOPS total
-t12 -w100 -b4k -W10 -o2 -d10 -Suw -D -L = 27-28 = 340 k IOPS total
Короткие тесты хоста NTFS 8k
Очень странный результат, я ожидал, что будет падение в разы.
По моему, я померял скорость кеша NVME .
-t8 -w0 -b4k -W10 -o2 -d10 -Suw -D -L = 44-44k 44 k IOPS per thread = 356k IOPS total
-t12 -w0 -b4k -W10 -o2 -d10 -Suw -D –L = 36-38 k IOPS per thread = 459 k IOPS total
-t8 -w100 -b4k -W10 -o2 -d10 -Suw -D –L = 39-39 k IOPS per thread = 315 k IOPS total
-t12 -w100 -b4k -W10 -o2 -d10 -Suw -D –L = 31-33 = 397 k IOPS total
В последнем тесте записано 16.275.570.688 байт = почти 16 Гб, столько оперативной памяти вроде там быть не должно.
Результаты рабочего теста хоста. 5 минут на тест (как оказалось, мало). NTFS 4k
-t8 -w0 -b4k -W10 -o16 -d300 -Suw -D -L = 29-30 = 239
-t12 -w0 -b4k -W10 -o16 -d300 -Suw -D –L = 25-28 = 325
-t8 -w100 -b4k -W10 -o16 -d300 -Suw -D –L = 14-15 = 120 . Вот и падение на запись появилось, куда ниже данных короткого теста.
-t12 -w100 -b4k -W10 -o16 -d300 -Suw -D -L = 9-10 = 119
Результаты рабочего теста хоста. 5 минут на тест (как оказалось, мало). NTFS 8k
-t8 -w0 -b4k -W10 -o16 -d300 -Suw -D –L = 38-39 = 313
-t12 -w0 -b4k -W10 -o16 -d300 -Suw -D –L = 29-32 = 371
-t8 -w100 -b4k -W10 -o16 -d300 -Suw -D –L = 12-12 = 102. Вот и падение на записи блоком 4к на диск с разметкой 8к. Было 120, стало 102. Точнее, было 15 на тред, стало 12 на тред. И это с включенным кешем на запись на уровне диска, который не понятно, учитывается при ключе -Suw или нет. И когда этот чекбокс применяется, до перезагрузки или после
-t12 -w100 -b4k -W10 -o16 -d300 -Suw -D -L – 7-7 = 94
окей, базовые цифры понятны.
Теперь то же самое, но с отключенным буфером записи на уровне дисков.
-t8 -w100 -b4k -W10 -o16 -d300 -Suw -D -L
NTFS4k = 14..14 = 117
NTFS8k = 12..12 = 100
окей, падение есть, но все же меньше 20%. По моему, я все равно буфер меряю.
Результаты теста VM Windows Server 2025 Evaluation с 8 ядрами и 24 Гб памяти
настройки VHDX: LogicalSectorSize : 4096 ; PhysicalSectorSize : 4096
NTFS 4k host, NTFS 4k внутри vhdx
-t6 -w0 -b4k -W10 -o16 -d300 -Suw -D -L = 4-93 = 390
-t8 -w0 -b4k -W10 -o16 -d300 -Suw -D -L = 9-75 = 475
-t6 -w100 -b4k -W10 -o16 -d300 -Suw -D -L = 9-10 = 61
-t8 -w100 -b4k -W10 -o16 -d10 -Suw -D –L = 10-14 = 90
Просадка идет по 2 потокам из 8, так что 6 физических ядер справляются полностью, но вот Hyper-V транслирует задачи на логические потоки AMD, видимо «так себе». Так что надо будет смотреть внимательнее, но у меня ни одного сервера на AMD нет. И в дальнейшем надо ограничивать виртуальные машины по числу физических ядер на виртуалку, если нужен максимум без просадок.
-t8 -w100 -b4k -W10 -o16 -d300 -Suw -D -L = 2.4 – 2.6 = 20
-t12 -w0 -b4k -W10 -o16 -d300 -Suw -D –L = 4-76 = 491
тесты на 12к тоже прошли, но они показывают только продолжение деления потоков.
NTFS 8k host, NTFS 4k внутри vhdx
-t6 -w0 -b4k -W10 -o16 -d300 -Suw -D -L = 4-94 = 404. При том, что три потока по 74.
-t8 -w0 -b4k -W10 -o16 -d10 -Suw -D –L = 9-63 = 416
-t8 -w100 -b4k -W10 -o16 -d10 -Suw -D -L = 1.8 = 14. Вот это падение. Причем тест длиной в 10 секунд.
-t8 -w0 -b4k -W10 -o16 -d300 -Suw -D –L= 9-78 = 482
-t8 -w100 -b4k -W10 -o16 -d300 -Suw -D –L = 2.5 = 20 . Падение .. какое-то.
Что из этого можно понять? Ничего, кроме того, что с тестами что-то не так.
Физика -t8 -w0 = 29-30 = 239
VM -t8 -w0 = 9-75 = 475.
Так быть не должно. И, очень может быть, что источник проблемы – кеширование дисков VM средствами ОС. Есть у Windows такая нехорошая привычка, втихаря кешировать файлы данных, пока оперативной памяти хоста хватает, и еще немного после. Видно это явление через Rammap, но отслеживать мне это явление крайне , крайне лень.
Обойдусь указанием на тот факт, что за 5 минут тестов «на запись» - динамические диски VM выросли всего до 13 Гб и 12 Гб. Значит, нужен тест не на 5 минут внутри VM, а часа на два. И на чтение такой же, чтобы система точно не успела откешировать.
Что ж. Поставлю тесты по 7200 секунд и пусть считает хоть всю ночь.
Все равно надо подобрать параметры, потому что на 8 виртуальных ядрах даже на 4 потоках получается какой-то ужасный разброс, типа 3 потока по 80 тысяч на чтение, и один поток на 7 (семь) тысяч на чтение, падение в 10 раз. Это не disk write caching, а или
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DynCache\Parameters]
или что-то отсюда же.
Начинаем тестирование по новой!
Итак, 6 vCPU Hyper-V в случае AMD, очень похоже что для Windows означают 6 потоков. Первые три потока распределяются на три физических ядра, следующие потоки начинают отправляться на исполнение на HT поток, но. Но если для физического хоста дисковые операции в diskspd идут почти без просадки, то для такого же diskspd изнутри VM это уже не так. Как итог, VM под Windows с 6 vCPU при трех дисковых потоках выполняет три потока без рассинхронизации, 4 потока идут уже с значительной просадкой одного потока, 5 и 6 потоков идут с просадкой в 10 (десять) раз.
таким образом, для VM на 10 vCPU должны исполняться до 5 потоков без существенной рассинхронизации.
Проверка.
-t2 -w0 = 161;165 = 327
-t3 -w0 = 76;75;76 = 227
-t4 -w0 = 26;26;26;26 = 107
-t5 -w0 = 32;32;32;32;1.2 = 131
При 5 потоках начался рассинхрон, причем разница не в 10, а в 30 раз, когда потоки получаются по 30 тысяч, и по 1.2 тысячи.
Значит, для 10 vCPU , максимальный имеющий смысл длительный тест – 4 потока, и 5 потоков подойдет для «мне только посмотреть».
При этом, практика на Intel серверах показывает, что для ряда задач ситуация совершенно другая.
Проводите измерения, пожалуйста, самостоятельно.
Внимание, все дальнейшие тесты выполнены с ВЫКЛЮЧЕННЫМ кешем на запись в свойствах диска хоста.
В гостевой системе Win server 2025 кеш диска на запись штатно не отключаем.
VM = 10 vCPU
Общие параметры теста -t2 -w0 -b4k -W10 -o16 -d5400 -Suw -D –L
-t2 -w0 NTFS4k = 190; 186 = 376
-t2 -w0 NTFS8k = 193;190 = 384
-t3 -w0 NTFS4k = 82;81;81 = 245
-t3 -w0 NTFS8k = 79;78;78 = 237
-t4 -w0 NTFS4k = 27;27;27;27 = 111
-t4 -w0 NTFS8k = 27;27;27;27 = 111
-t5 -w0 NTFS4k = 31;31;31;31,1 = 128
-t5 -w0 NTFS8k = 24;24;24;24,0.8 = 99
-t5 -w100 NTFS4k = 11,11,11,11,11 = 56
-t5 -w100 NTFS8k = 9,9,9,9,9 = 48
Итого, для 10 vCPU –
Для 4 потоков на чтение еще соблюдается баланс между потоками. На 5 потоках уже нет баланса на чтение.
Для 5 потоков на запись – какой-то баланс еще есть.
Побочное открытие. Поскольку файл с данными для diskspd лежит на тонком томе, и не вырос, то получается, что случайное чтение идет не с реальных данных какого-то паттерна, а с не записанных данных. То есть вопрос, а что система читает, ответ драйвера «0» в большей части случаев, поскольку фактический размер тестовых файлов 10-12 гб?
Прочие инструменты тестирования
Кроме ранее упомянутых тестов SQLsim и HammerDB
Есть статья (перевод: Рекомендации по тестам производительности для Azure NetApp Files) с рекомендованными инструментами:
Sql Storage Benchmark (SSB) и FIO.
Для FIO сделаны рекомендации
fio --name=8krandomreads --rw=randread --direct=1 --ioengine=libaio --bs=8k --numjobs=4 --iodepth=128 --size=4G --runtime=600 --group_reporting
с комментарием, цитата:
Эти сценарии охватывают как кэширование, так и обход кэширования для случайных рабочих нагрузок ввода-вывода с помощью параметров FIO (в частности, randrepeat=0 для предотвращения кэширования в хранилище и directio, чтобы предотвратить кэширование на клиенте).
При этом, что не менее интересно, изнутри VM с Windiws – diskSPD видит систему как:
cpu count: 10
core count: 5
Как при этом работает CPU scheduler в ОС гипервизора и ОС гостевой системы – я не понимаю. Возможно, надо делать 6 ядер для гостевой ОС, и в Hyper-V указывать threads per core =1 , а не оставлять по умолчанию.
Какие можно сделать промежуточные выводы?
30 секундные, 1-5 минутные тесты показывают кеширование. Реальная производительность после 1-2 часов тестирования будет отличаться. И это я еще не рассматриваю проблему домашних SSD дисков с работой в «пустом» режиме, с 50% заполнением и с 75% заполнением, вот там могут начинаться совсем другие истории по скорости работы.
Для точки отсчета можно принять следующие данные:
Для 4 потоков чтения с хоста можно иметь стабильные 50 тысяч IOPS на чтение на поток, всего 200 тысяч. /
Все данные ниже, относительно IOPS, указаны в тысячах IOPS.
Host = -t3 -w0 = 52, 52, 82, = 186
Host = -t3 -w100 = 28,28,44 = 100 (NTFS 4k)
Host = -t3 -w100 = 22,22,34 = 78 (NTFS 8k)
VM = -t3 -w0 = 76;75;76 = 227 (все цифры в тысячах IOPS).
Балансировщик IO \ CPU в Windows 11 для NVME работает не очень предсказуемо, но достаточно балансируемо. Можно покрутить minroot, но это избыточно для данного текста.
diskspd дает повторяемые результаты, что уже и неплохо.
Linux VM , 10 vCPU, 24 Gb RAM
ОС (заодно и обновил) - Debian12
Было: 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22)
Стало: 6.1.0-38-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.147-1 (2025-08-02)
Разомнемся:
fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=fiotest --filename=testfio --bs=4k --iodepth=64 --size=8G --readwrite=randrw --rwmixread=75
read: IOPS=95.3k, BW=372MiB/s (390MB/s)(6141MiB/16494msec)
Сделаю файл настроек, чтобы было чуть нагляднее.
nano fiotest_001.test с содержанием, цитата:
[global]
name=fiotest123
ioengine=libaio
direct=1
iodepth=16
bs=4k
group_reporting
runtime=300
startdelay=10
rw=randread
size=32Gb
numjobs=3
filename=delme_after.test
[test1234]
Как оказалось, group_reporting работает крайне, крайне странно.
Ещё спроси а где тут вожжи, ещё поехали скажи
echo '11=====' ; date ; echo '22====='; fio fiotest_001.test ; echo '33==========='
Пометки? Или параметр group_reporting вовсе не лишний ?? Потому что английским по белому сказано, цитата:
After the test is completed (or cancelled with Ctrl+C), the Fio will generate a detailed report showing more details. If --group_reporting attribute was used, it will show the summary for all the threads together, but if it wasn't used, the details will be shown for each thread separately and it may be confusing.
Что мешало сделать авторам вывод [total] без использования [group_reporting], не понятно. Переписывать тест я, конечно, не буду.
Но, к цифрам:
read: IOPS=126k, что меньше, чем с хоста, но больше, чем с непонятно как отработавшего теста внутри VM Windows server 2025.
Детальнее:
iops : min=26524, max=68224, avg=43534.54, stdev=8559
iops : min=22610, max=68030, avg=43995.81, stdev=8268
iops : min=26540, max=63692, avg=44087.64, stdev=7910
Данные куда понятнее, чем diskspd, видно и среднее, и максимум, и разброс. Хороший такой разброс, надо сказать.
Поправлю файл конфига, допишу:
[test1234]
numjobs=5
И получу
iops : min=18646, max=78609, avg=33717.05, stdev=6821
iops : min=13126, max=58088, avg=34077.43, stdev=6590
iops : min=14158, max=54144, avg=34087.76, stdev=6473
iops : min=15500, max=56756, avg=33983.17, stdev=6233
iops : min=14676, max=52144, avg=34009.63, stdev=6541
Допишу
[test1234]
numjobs=5
group_reporting
(Минута нытья) как же все непривычно в выводе, детализация богатая, но не читаемая. Зато время до конца теста показывается. И сумма IOPS не совпадает и никак не бьется с настройкой group_reporting и без нее.
с ней
read: IOPS=124k, BW=483MiB/s (507MB/s)(142GiB/300002msec)
iops : min=59479, max=242247, avg=123919.97, stdev=5378
Но 5 потоков по 30-35 в сумме дают 170 k IOPS, а не 124. Такое впечатление, что настройка
[global]
numjobs=3
[test1234]
numjobs=5
Проводит пять тестов (в отчете - Starting 5 processes), но считает статистику за три первых потока (Jobs: 3 (f=3) )
Не тесты, а какая-то неведомая лажа.
Я буду жаловаться в спортлото!
Для Proxmox 9 (Debian 13) внутри Hyper-V, CPU nested.
Настройки те же, 10vCPU \ 24 RAM
numjobs=3
iops : min=26250, max=86042, avg=44499.43, stdev=18314
iops : min=34930, max=62044, avg=54114.53, stdev=7103
iops : min=28046, max=71702, avg=50969.20, stdev=11388
numjobs=5
iops : min=11804, max=33632, avg=28052.91, stdev=3660
iops : min=11694, max=33590, avg=27945.52, stdev=3794
iops : min=17816, max=43656, avg=27950.35, stdev=3753
iops : min=10628, max=43976, avg=27898.52, stdev=3993
iops : min=16428, max=34810, avg=27951.97, stdev=3732
numjobs=5 плюс group_reporting
read: IOPS=81.9k, BW=320MiB/s (при конфликте [global] и [test1234])
read: IOPS=98.7k, BW=386MiB/s (при одинаковой настройке [global] и [test1234])
Один и тот же тест.
Расчет group_reporting для двух потоков
group_reporting считает что-то свое, в зависимости от настроек numjobs в [global] – 2/1 или 2/2, и того где указан group_reporting – в [global] или в [test]
iops : min= 5434, max=41258, avg=30155.54, stdev=6075
iops : min= 5442, max=40952, avg=30271.04, stdev=6121
iops : min=90444, max=184954, avg=131080.09, stdev=10288 (group_reporting )
iops : min= 8630, max=85296, avg=59160.71, stdev=7513 (group_reporting - global)
или
iops : min=24398, max=44548, avg=33152.11, stdev=3566
iops : min=25010, max=43772, avg=33056.37, stdev=3417
iops : min=49320, max=163531, avg=78313.81, stdev=11188 (group_reporting )
Надо везде мерять fio, если будет сравнение Windows \Linux , и сразу готовить какой-то авто парсер результатов.
Тестирование короче хотя бы 15-30 минут на тест , и с размерами тестового файла меньше оперативной памяти позволяет только проверить работу скрипта. Может, покажет какие-то цифры скорости работы кеширования.
Параметр group_reporting для fio рассчитывается как-то странно.
Планировщик задач в Windows server, Debian 12 и Debian 13 работает по разному.
Debian 12 VM и Debian 13 (proxmox) CPU nested дают разброс вида
Deb12 iops : min=26524, max=68224, avg=43534.54, stdev=8559
Deb13 iops : min=26250, max=86042, avg=44499.43, stdev=18314
Даже средние показатели могут сильно расходиться.
Один плюс – сами тесты делались в основном ночью, потратил только час на сведение всего этого в одну большую, не читаемую, кучу.