Pull to refresh

Comments 105

— Сюрприз, но NVMe-диски работают на считаные проценты лучше SSD-дисков. А мы ведь ждали совсем даже не этого.

Используйте устройства не из низшего ценового сегмента. Интеловые DC-grade NVME накопители объективно выдают показатели, недостижимые для других шин (sas, sata). В любом из бенчмарков.

Софтрейд роняет производительность nvme, и это легко обнаружить, если собрать raid0 из 1920 ramd-disk'ов. Для двух дисков падение производительности не такое радикальное.

При тестировании nvme критически важным становится время выполнения системного вызова. Попробуйте использовать ПО с поддержкой io_uring, а ещё лучше, ОС, которая запускает ELF-файлы, а не 'е-хе'.

Перед тем, как измерять производительность nvme, проверьте, что ваши утилиты такое выдержат. null_blk - хорошее начало. Тот же fio начинает страдать на 3-4 миллионах iops'ов, а теоретический лимит имеет в 20 миллионов (на null устройстве без вызовов ядра).

Используйте устройства не из низшего ценового сегмента. 

У них тут как раз все ок. Если все как в прошлой статье, то они используют Intel SSD DC P4610 Series 1.6TB, 2.5in PCIe 3.1 x4, 3D2, TLC Круче уж некуда.

Тогда я не понимаю, как они сумели "разогнать" SAS/SATA до PCI-E скоростей. Вот так вот взять и выдать 3ГБ/с на sas? Не верю. Так же как и в 500к IOPS на sata (потому что при 4к блоках это 2ГБ/с).

Мы подключали диски к PCI-E через U.2 интерфейс, в статье это указано. Более того приведена диаграмма разводки линий материнской платы.

А вы производительность виртуализации-то тестировали? Я вот с интересом наблюдал разницу в 10 раз в работе nullblk между бареметаллом и VM (при том, что nullblk вообще никаких внешних устройств не требует). latency переключения userspace/kernel у VM кратно выше, чем у BM, и чем лучше nvme, тем больше это начинает влиять.

Тестировали, но там тесты другого плана. Создается множество виртуальных машин, чтобы забить сервер «под завязку». На всех ВМ одновременно запускается тест диска. После этого собирается суммарный результат со всех виртуалок. Суммарный результат будет ниже чем при тестах с хостовой машины, но не принципиально. В рамках отдельной ВМ, производительность намного ниже, чем на «бареметалле».

Тогда я не понимаю с какой sas/sata SSD вы сумели 500000 IOPS получить, чтобы жаловаться, что "единицы процентов по сравнению с обычными SSD".

NVMe вроде хвалят за низкую латентность. Если ядро часто переключает контекст и латентность переключения много больше NVMe, то подозреваю, что наоборот, разница между SATA SSD и NVMe будет труднее обнаружить.

Кстати, вот пример сравнения Baremetal https://elibsystem.ru/node/503 с Hyper-V, KVM на SATA SSD c древним контроллером, но и там довольно хорошо видна сильная зависимость производительности от гипервизора.

Вообще надо понять что тестировать-то хочется.

Абстрактную производительность NVMe? Производительность NVMe в Hyper-V в одиночной ВМ (не убивает ли оверхед Hyper-V низкую задержку NVMe)? Производительность NVMe при большом количестве ВМ, все из которых одновременно генерируют нагрузку по сравнению с SATA (качественное сравнение есть ли разница при большой нагрузке в условиях конкуренции кучи ВМ за CPU и NVMe)? Во всех трех случаях очевидно методика тестирования разная.

Более того, от того пишутся ли данные синхронно или последовательно тоже результаты бенчмарка зависят, а тут сюрприз, SSD часто нужны для баз данных, а РСУБД пишут часто последовательно (потому-что в журнал) малым количеством потоков с частыми fsync. Т.е. базы данных даже близко не выдают максимально возможные IOPS-ы на запись.

Дальше надо понимать, что NVMe хороши низкой задержкой. Но! Но когда 100500 ВМ генерируют параллельно нагрузку и утилизируют SSD в полку, общая пропускная способность конечно будет высокой (у SSD чем больше одновременных потоков - тем больше IOPS и мегабайт), но вот задержки начнут сильно нарастать, а в статье задержки вообще не представлены! Т.е. при миллионе IOPS задержки какие? Вот для примера про латентность от Intel:

Поэтому зная, что все зависит от всего (производительность от нагрузки случайная/последовательная, размера кластера, как часто fsync шлется, размера очереди, конкуренции за CPU множества ВМ, драйверов, ФС, гипервизора, writeback, способности ВМ читать из ОЗУ вместо диска из-за виртуализации и т.д.) надо, ну если хочется во всех этих аспектах посмотреть что происходит, делать не один тест, а на каждую из задач по тесту.

Естественно, синтетика с большим количеством очередей может совершенно не походить по профилю нагрузки на поведение баз данных. Так что логично поинтересоваться у клиентов какие базы гонять собираются и побенчмаркать базы на NVMe/SATA и посмотреть, есть ли разница. Естественно начинаются приколы, что SATA будет контроллер использовать и он тоже может и свои настройки иметь и задеркжи и т.д.

Итого: непростое это дело производительность дисковой подсистемы измерять!

NVMe вроде хвалят за низкую латентность.

при времени доступа к nand >>50 мкс задержки шины уже особой роли не играют

Все немного сложнее получается. Появляется дополнительный программный слой и дополнительный аппаратный (контроллер).

Только вчера читал тестирование PostgreSQL 2014 года и на SATA у них было что-то там 50 тыс. tps, а на NVMe 400 тыс. tps, а в RAM если диск держать 1500 тыс. tps.

Люди смотрят на такие бенчмарки и хотят, конечно, NVMe и почти x10 к работе базы.

Появляется дополнительный программный слой и дополнительный аппаратный (контроллер).

вы про sata?


так и nvme не обходится без программного слоя )
да, на один контроллер в цепочке cpu — nand в случае nvme меньше, но узким местом является не наличие контроллера само по себе, а достаточно узкая шина между ним и накопителем.


Только вчера читал тестирование PostgreSQL 2014 года и на SATA у них было что-то там 50 тыс. tps, а на NVMe 400 тыс. tps, а в RAM если диск держать 1500 тыс. tps.

ну это очень специфичная нагрузка, почти наверняка синтетика.


ноги растут из hdd: в те времена запросы накопители обрабатывали долго, накапливалась очередь. так как время доступа определяется механикой, то единственным способом улучшить производительность было увеличение числа шпинделей, а большие очереди — с одной стороны нормой, с другой — единственным способом утилизировать потенциальную производительность дисковой системы.
с приходом ssd ситуация в корне поменялась, среднее время доступа из 5-10 мс стало 50-100 мкс, то есть на два порядка ниже (притом, как я писал выше, оно определяется nand, и особо не зависит от интерфейса); плюс оно практически не растёт до до некоторого порога нагрузки (на hdd оно растёт лавинообразно при qd>1 на шпиндель), в результате выигрыш в производительности в сравнении с hdd несколько порядков.
в итоге, до некоторой (и достаточно большой для реальной жизни) нагрузки все ssd независимо от интерфейса примерно одинаковы, потом сдаётся sata, потом sas, ну а у nvme самый высокий потенциал.


ну так вот, привычка тестировать дисковую подсистему с глубиной очереди 100500 никуда не делась со времён hdd, только к реальным нагрузкам это тестирование имеет мало отношения.


условная аналогия: мы сравниваем суперкары по скорости разгона с 200 км/ч до 300 км/ч, да, это сравнение покажет какой кар круче, но к скорости передвижения в городском потоке это будет иметь мало отношения (скорость разгона до 80 км/ч, более актуальная в городе, у них, скорее всего, окажется примерно одинаковой).


P. S. весь этот текст был про случайный доступ, на последовательном sata сдаётся достаточно рано, на каких-нибудь бэкапах разница между sata и sas/nvme может быть видна невооружённым глазом.


P. P. S. с другой стороны, сегодня nvme накопители обычно стоят примерно как sata, поэтому выбирать sata никакого смысла нет. sas ssd же вообще для меня какая-то экзотика )

Postgres там наверняка тестировали "стандартным" pgbench.

ну так вот, привычка тестировать дисковую подсистему с глубиной очереди 100500 никуда не делась со времён hdd

С малой глубиной ни о каких 1+ млн. IOPS или 7 ГБ/c не может быть и речи. Так что это не привычка, а маркетинг -)

Вот для примера латентность на корпоративном SSD Intel вот отсюда.

Вот еще пример того же источника, что разные SSD могут себя сильно по разному вести при записи.

А это пример пользовательского SSD, у которого латентность 5 мс (как у HDD) уже при 25 тыс. IOPS.

Латентность - важная величина. NVMe для баз данных именно за нее и выбирают (NAND-то одинаковая и в SATA и в NVMe). Поэтому её стоит приводить в бенчмарках.

А это пример пользовательского SSD, у которого латентность 5 мс (как у HDD) уже при 25 тыс. IOPS.

так это не sata виновата, это накопитель такой )
запустил на своём s3510 чтение в 4 потока, получил 30к iops и задержки 130 мкс. в 8 потоков 150 мкс. в 16 250 мкс (вот тут уже начал насыщаться контроллер на ssd; напоминаю, что это накопитель начального уровня).
заметьте, до насыщения шины ещё далеко, она не утилизирована ещё и наполовину, так что дело точно не в шине, а в самом накопителе.


Латентность — важная величина. NVMe для баз данных именно за нее и выбирают (NAND-то одинаковая и в SATA и в NVMe). Поэтому её стоит приводить в бенчмарках.

на самом деле время доступа/иопсы/мегабайты в секунду элементарно пересчитываются друг в друга.
из теста в предыдущем абзаце 130 мкс задержки в 4 потока на блоках 4 КБ эквиваленты 4/130e-6 ≈ 30к iops или же 120 МБ/с.


напомню, что я изначально написал


при времени доступа к nand >>50 мкс задержки шины уже особой роли не играют

при qd=1 время доступа чтения будет примерно 100 мкс что на sata, что на nvme накопителях.
и при qd=4, и при qd=8 тоже, я вам показал. и даже при qd=16 цифры сопоставимы.


да, при qd=1024 время доступа у nvme будет в разы меньше (а иопсы пропорционально выше), но если у вас на сервере qd=1024, то, скорее всего, что-то пошло не так.


на своих нагрузках разницу между sata и nvme накопителями в БД я вижу только в задачах вроде бэкапов; в типичной нагрузке на базу данных (если там нет seqscan'ов) разницы нет.
впрочем, повторюсь, сейчас sata ssd по сути уже не дешевле nvme, так что смысла выбирать sata нет.

Зная IOPS можно узнать и пропускную способность, умножив IOPS на размер блока. 30 000 IOPS x 4K = 120 000 K/s. = 117 MB/s.

А вот как латентность вычислить из IOPS? Графики выше явно говорят, что зависимость не линейная, т.е. вычислить латентность из IOPS нельзя.

Вернее так, если у вас бенчмарк имеет глубину 1 и 1 очередь, то да, время за которое у вас выполнится одна операция и придет подтверждение ее выполнения и является латентностью по определению. Т.е. 1/(число IOPS) = время 1 операции.

По мере роста глубины и потоков у вас латентность становится больше среднего времени выполнения операций за некоторое время. Т.е. вычислять латентность при Q>1 и T>1 делением 1 на IOPS нельзя.

IOPS=QD/latency


небольшая ошибка набегает из-за усреднений, но обычно это единицы процентов.

fio --filename=/fio.test --size=20G --direct=1 --rw=randrw --bs=4k --ioengine=libaio --iodepth=10 --iodepth_batch_submit=10 --runtime=60 --numjobs=1 --time_based --group_reporting --name=iops-test-job --eta-newline=10
Результаты
 read: IOPS=763, BW=3056KiB/s (3129kB/s)(183MiB/61231msec)
    slat (usec): min=4, max=785, avg=47.21, stdev=34.87
    clat (usec): min=6, max=10070k, avg=5071.20, stdev=190536.81
     lat (usec): min=273, max=10070k, avg=5118.44, stdev=190537.01
    clat percentiles (usec):
     |  1.00th=[    343],  5.00th=[    388], 10.00th=[    408],
     | 20.00th=[    433], 30.00th=[    449], 40.00th=[    465],
     | 50.00th=[    478], 60.00th=[    490], 70.00th=[    502],
     | 80.00th=[    519], 90.00th=[    545], 95.00th=[    570],
     | 99.00th=[   1254], 99.50th=[   1319], 99.90th=[   2008],
     | 99.95th=[2164261], 99.99th=[9999221]
   bw (  KiB/s): min=  280, max=38896, per=100.00%, avg=18225.65, stdev=14831.77, samples=20
   iops        : min=   70, max= 9724, avg=4556.40, stdev=3707.93, samples=20
  write: IOPS=759, BW=3037KiB/s (3109kB/s)(182MiB/61231msec); 0 zone resets
    slat (usec): min=8, max=10069k, avg=1263.95, stdev=100212.07
    clat (usec): min=21, max=10070k, avg=6754.43, stdev=231949.00
     lat (usec): min=262, max=10070k, avg=8018.41, stdev=252641.24
    clat percentiles (usec):
     |  1.00th=[     347],  5.00th=[     383], 10.00th=[     408],
     | 20.00th=[     433], 30.00th=[     449], 40.00th=[     465],
     | 50.00th=[     478], 60.00th=[     490], 70.00th=[     502],
     | 80.00th=[     519], 90.00th=[     545], 95.00th=[     570],
     | 99.00th=[    1254], 99.50th=[    1319], 99.90th=[    2024],
     | 99.95th=[ 7415530], 99.99th=[10133439]
   bw (  KiB/s): min=  376, max=38544, per=100.00%, avg=18102.80, stdev=14618.84, samples=20
   iops        : min=   94, max= 9636, avg=4525.70, stdev=3654.71, samples=20
  lat (usec)   : 10=0.01%, 50=0.01%, 100=0.01%, 250=0.02%, 500=67.58%
  lat (usec)   : 750=30.48%, 1000=0.01%
  lat (msec)   : 2=1.80%, 4=0.03%, >=2000=0.08%

Очередь 10, IOPS 5000, Вычисляем по формуле latency = QD/IOPS = 2 мс. А измеренная по бенчмарку 5-8 мс с большим среднеквадратичным отклонением.

Это можно и наглядно показать, что просто так задержку не стоит из IOPS вычислять.

а что не так-то?


по вашей картинке:
iops=10/t (за t секунд произошло 10 операций)
latency≈t


по предложенной формуле:
latency≈qd/iops=10/(10/t)=t

1) Не смущает, что на рисунке latency примерно 2/3 t? Причем что t=1сек - это сущий произвол и вообще-то t может быть 1 мс и вообще сколько угодно.

2) Я привел реальные измерения с помощью fio и в них latency больше в разы указанной формулы.

3) Вот еще рисунок в котором допустим два разных SSD с разной latency.

Можно, конечно, сказать, что IOPSы здесь неправильно нарисованы и надо все заштриховать, но когда вы все заштрихуете (упретесь в возможности контроллера, забив его длинной очередью), у вас скорее всего из-за неспособности больше операций прожевать latency начнет сильно расти, возможно экспоненциально. С огромной дисперсией. Причем рост начнется не по забиванию контроллера, а даже раньше, когда забьете очередью каналы в контроллере, кеши и какие-нибудь другие ресурсы, которые внутрях есть.
Ну и на графики StorageReview выше посмотрите. Вы видите на них ту зависимость latency ~ 1/IOPS? Я вот не вижу.

Поэтому вот, надо измерять.

Не смущает, что на рисунке latency примерно 2/3 t?

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


Вот еще рисунок в котором допустим два разных SSD с разной latency.

честно говоря, не понимаю, что вы хотите этими картинками показать.
в обоих случаях формула latency ≈ qd/iops будет более-менее работать (более-менее потому, что непонятно как точно считать iops на интервалах, соизмеримых с задержкой ввода/вывода)


Можно, конечно, сказать, что IOPSы здесь неправильно нарисованы и надо все заштриховать, но когда вы все заштрихуете (упретесь в возможности контроллера, забив его длинной очередью), у вас скорее всего из-за неспособности больше операций прожевать latency начнет сильно расти, возможно экспоненциально. С огромной дисперсией. Причем рост начнется не по забиванию контроллера, а даже раньше, когда забьете очередью каналы в контроллере, кеши и какие-нибудь другие ресурсы, которые внутрях есть.

не понял что вы имеете в виду под «всё заштриховать».
увеличить qd? так мы пока говорили про измерения с постоянной (не важно какой, важно, что не меняющейся в процессе теста) глубиной очереди.


Ну и на графики StorageReview выше посмотрите. Вы видите на них ту зависимость latency ~ 1/IOPS?

а где там графики с постоянной qd?


сама идея не ограничивать qd, а ограничивать iops и строить зависимость latency от iops мне нравится, но вот реализация на storagereview не выдерживает никакой критики — из-за того, что на графики попадают секундные «хвосты», разглядеть задержки в левой части графика проблематично, а таблиц с числовыми значениями сходу я не нашёл.

вывод аналогичной команды на моём сервере
  read: IOPS=92.2k, BW=360MiB/s (378MB/s)(21.1GiB/60001msec)
    slat (nsec): min=1020, max=111660, avg=1461.82, stdev=654.72
    clat (usec): min=32, max=8869, avg=93.21, stdev=73.93
     lat (usec): min=56, max=8871, avg=94.68, stdev=73.90
    clat percentiles (usec):
     |  1.00th=[   58],  5.00th=[   59], 10.00th=[   60], 20.00th=[   62],
     | 30.00th=[   65], 40.00th=[   69], 50.00th=[   71], 60.00th=[   75],
     | 70.00th=[   83], 80.00th=[  102], 90.00th=[  139], 95.00th=[  212],
     | 99.00th=[  424], 99.50th=[  553], 99.90th=[  832], 99.95th=[  930],
     | 99.99th=[ 1090]
   bw (  KiB/s): min=242680, max=453656, per=99.86%, avg=368407.06, stdev=95599.96, samples=119
   iops        : min=60670, max=113414, avg=92101.76, stdev=23899.99, samples=119
  write: IOPS=92.2k, BW=360MiB/s (377MB/s)(21.1GiB/60001msec); 0 zone resets
    slat (nsec): min=1040, max=84435, avg=1557.34, stdev=671.25
    clat (nsec): min=240, max=131324, avg=11360.38, stdev=2080.01
     lat (usec): min=9, max=132, avg=12.92, stdev= 2.15
    clat percentiles (nsec):
     |  1.00th=[ 8512],  5.00th=[ 9024], 10.00th=[ 9536], 20.00th=[ 9792],
     | 30.00th=[10048], 40.00th=[10432], 50.00th=[10816], 60.00th=[11200],
     | 70.00th=[11840], 80.00th=[12736], 90.00th=[14016], 95.00th=[15296],
     | 99.00th=[18816], 99.50th=[20096], 99.90th=[22912], 99.95th=[24192],
     | 99.99th=[28032]
   bw (  KiB/s): min=240904, max=453264, per=99.87%, avg=368153.55, stdev=95399.17, samples=119
   iops        : min=60226, max=113316, avg=92038.39, stdev=23849.79, samples=119
  lat (nsec)   : 250=0.01%, 500=0.01%
  lat (usec)   : 2=0.01%, 4=0.01%, 10=13.86%, 20=35.86%, 50=0.26%
  lat (usec)   : 100=39.36%, 250=8.93%, 500=1.40%, 750=0.25%, 1000=0.07%
  lat (msec)   : 2=0.01%, 4=0.01%, 10=0.01%
  cpu          : usr=21.25%, sys=30.90%, ctx=4318157, majf=0, minf=22
  IO depths    : 1=0.0%, 2=0.0%, 4=0.0%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 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%
     issued rwts: total=5533873,5529334,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=10

Run status group 0 (all jobs):
   READ: bw=360MiB/s (378MB/s), 360MiB/s-360MiB/s (378MB/s-378MB/s), io=21.1GiB (22.7GB), run=60001-60001msec
  WRITE: bw=360MiB/s (377MB/s), 360MiB/s-360MiB/s (377MB/s-377MB/s), io=21.1GiB (22.6GB), run=60001-60001msec

имеем 92.2к iops на чтение + 92.2к iops на запись, считаем
latency = 10 / (92200 + 92200) ≈ 54.23 мкс


измеренное же fio значение (94.68 + 12.92) / 2 = 53.80 мкс, отличие менее 1%.


почему в вашем примере не так — сходу не могу сказать.
подозреваю, что среднее значение iops в вашем примере «показывает погоду на марсе», но, к сожалению, за несколько минут я не смог разобраться как именно оно считается в fio.

Очередь 10, IOPS 5000

я думаю, что там всё-таки совсем другое среднее значение iops.


  read: IOPS=763, BW=3056KiB/s (3129kB/s)(183MiB/61231msec)
  write: IOPS=759, BW=3037KiB/s (3109kB/s)(182MiB/61231msec); 0 zone resets

763 и 759 выглядят более правдоподобно, в этом случае задержка получается
10 / (763 + 759) ≈ 0.006570 с = 6570 мкс.


измеренная fio
(5071 + 8018) / 2 = 6544.5


опять неплохо сходится.


не могли бы вы повторить тест с параметрами write_iops_log и write_lat_log и выложить результат? хочу попробовать разобраться откуда взялись 5000 iops.

А это пример пользовательского SSD, у которого латентность 5 мс (как у HDD) уже при 25 тыс. IOPS.

сейчас на глаза попался обзор nvme-накопителя на qlc:
image
Что, сынку, помогли тебе твои ляхи pci-e gen4?

Дай дураку стеклянный уй, он им порежется.
Кто покупает qlc для задач на запись?

Даже не сомневайтесь, находятся. А как массово пойдут дешёвые qlc — так повсеместно их и будут брать под любые задачи. По моему опыту DBA — многие в принципе не понимают, что SSD бывают разные. В их картине мира есть HDD и есть SSD. И всё. А при попытке выяснить, какие именно стоят SSD, потому что мне из виртуалки не посмотреть — полное непонимание вопроса в глазах, ну ssd же у нас куплены, в чём вопрос?

ну справедливости ради, тех ≈10к iops, на которых, судя по картинке, затыкается этот intel, хватит для очень многих БД.
скорее для БД опасны десктопные ssd, которые могут изрядно тормозить на fsync.

У админов-сетевиков есть фраза "проблема всегда в DNS". У админов виртуализации видимо аналог - "проблема всегда в NUMA" :)

Они могут чуть ли не Делл из Супермикро собрать

Ирония в том, что делл и прочие супермикро и использует для некоторых моделей.

А про NUMA да, это штука известная. Я поэтому очень люблю супермикро за их документацию. К каждому серваку есть мануал с блоксхемой всех компонентов на материнке, что позволяет сразу оценить, где может быть ботлнек. Очень важно для любой pcie нагрузки, будь это диски или гпу. Терпеть не могу энтерпрайз этот, где толком не поймешь даже сколько у тебя райзеров pcie и каких будет. Куда уж там сколько pcie линий и откуда отведено под тот или иной порт.

Вот насчет рейда все равно не уверен. Какой-нить raid0 должен дать профит. Тут мне кажется сильно зависит от софта, т.к. pcie диски требует очень серьезной работы уже в софте, чтобы правильно раскидать потоки по ядрам, правильно шедулить запросы к дискам, минимизировать общение через интерконнект процессоров и т.д. и т.п.

По совести, у dell'а есть подробные блок-схемы именно в контексте nvme, потому что это (внезапно стало) важно. Там же написано в каких конфигурациях производительность будет ограничиваться (из-за сожительства nvme на одной линии).

У IBM всё вполне разрисовано и бест практики.

мы надеемся, что дополнительная UPI-линия может убрать необходимость разделять виртуалки по NUMA-нодам

Очень хочется узнать результаты )

План такой. Сделать каждый нума узел одинаковым и при старте процесса пинить его на нумаузел и выдавать ближайший NVME, исключив "по умолчанию виртуалки распределяются по NUMA-нодам в хаотичном порядке". Попробовать поиграться с настройками SNC в биосе. SNC 2 будет в этом случае достаточно.

Настройки BIOS безусловно важны, но нам важно, чтобы виртуальная машина попала на ту NUMA-ноду, CPU которой обслуживает NVME диск, на котором расположен образ VM. В этом случае для обращения к диску виртуальной машине не потребуется задействовать UPI линии.
но нам важно, чтобы виртуальная машина попала на ту NUMA-ноду, CPU которой обслуживает NVME диск, на котором расположен образ VM. В этом случае для обращения к диску виртуальной машине не потребуется задействовать UPI линии.

а зачем вам вообще двухядерные серверы?

Больше процессоров в одном юните

А не проще использовать 1 cpu на 64 ядра, например, без плясок с бубнами?

Не до конца понятно, какой процессор с 64 ядрами вы имеете ввиду, как правило они не подходят для нужд хостинга.

Intel Xeon Phi Processor 7210 — слишком низкая частота.
AMD Ryzen Threadripper 3990X Processor — слишком мало каналов памяти.

Вы как то упустили как раз то, что исходят из первой статьи вам было нужно.

Ryzen Threadripper Pro 3995WX.

64 ядра, 128 линий PCie 4 версии, 8 каналов оперативной памяти, и объем до 2ТБ.

При этом буст частота - до 4.2Ггц.

Это хоть и тредрипер, но по сути именно что серверный эпик, с апнутыми частотами. А если не нужен такой монстр - вполне вариант к примеру Ryzen Threadripper Pro 3955WX, как раз замеит два ваших 8 ядерника, базовая частота те же 3.9, буст 4.3, остальное так же что и у того что описывал выше.

И чем TDP с него снимать в условном 1u корпусе? Там же явно за 250+ уходит

Тот же супермикро вполне себе заявляет поддержку в однопроцессорной системе без доп ограничений. Даже для двухпроцессорных систем поддержка есть, но в определенных условиях.

Те, кто пишет про RAID, либо банально врут, либо замедляют скорость чуть ли не ниже SSD, что исключает полезность NVMe-дисков.

Получается Hetzner врёт? Они утверждают что у них RAID10 на хостах, диски NVMe, и судя по результатам тестирования внутри cloud-серверов, похоже таки на правду (fio на самом дешёвом cloud server, CX11, ему уже несколько лет):


# fio --filename=/fio.test --size=1G --direct=1 --rw=randrw --bs=1m --ioengine=libaio --iodepth=8 --iodepth_batch_submit=8 --runtime=10 --numjobs=6 --time_based --group_reporting --name=iops-test-job --eta-newline=1
...
Run status group 0 (all jobs):
   READ: bw=2894MiB/s (3034MB/s), 2894MiB/s-2894MiB/s (3034MB/s-3034MB/s), io=28.3GiB (30.4GB), run=10012-10012msec
  WRITE: bw=2919MiB/s (3061MB/s), 2919MiB/s-2919MiB/s (3061MB/s-3061MB/s), io=28.5GiB (30.6GB), run=10012-10012msec

## А также чистая запись

# fio --filename=/fio.test --size=1G --direct=1 --rw=randwrite --bs=1m --ioengine=libaio --iodepth=8 --iodepth_batch_submit=8 --runtime=10 --numjobs=6 --time_based --group_reporting --name=iops-test-job --eta-newline=1
iops-test-job: (g=0): rw=randwrite, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=libaio, iodepth=8
...
Run status group 0 (all jobs):
  WRITE: bw=4560MiB/s (4781MB/s), 4560MiB/s-4560MiB/s (4781MB/s-4781MB/s), io=44.6GiB (47.8GB), run=10008-10008msec

В процессе тестирования использование процессора (vCPU, он там один) около 60%.


По любому быстрее чем обычный SSD — в разы. Результаты стабильные за все несколько лет, и не только на одном сервере, разумеется, и это с учётом того что на одном хосте крутится явно не один виртуальный.

Причина скорее всего в том, что в качестве технологии виртуализации хетцнер использует KVM, а статья о hiper-v. Субьективно никогда не нравился hiper-v, как и многие другие проприетарные решения.

Если там стоит аппаратный контроллер с writeback, есть вероятность, что все записанные данные уместились в его ОЗУ и это тест скорости ОЗУ контроллера.

А чего вы там за 10 сек намеряете то? Уберите параметр --runtime=10, дайте тесту поработать на объём выше объёма кеша. На полный прогон теста на 100%. Результаты могут оказаться совсем не теми, что вы ожидаете.

Вот этот тест на 1МБ блок, это совсем не то кстати, что у вас в продуктиве происходит. Выглядит как маркетинг для консамерского рынка.

Блок на 4КВ лучше выставить наверное. Это будет типичный блок. А с 1М блоком тест закончится не успев запустить все потоки. С 1М блоком, тест внезапно становится более последовательный чем случайный.

На домашней системе RAID-10 на 6 SATA дисках (ZFS), против Samsung EVO 980 Pro 1TB. Смотрим разницу для размера блока:

ZFS-RAID10(compression lz4):

fio --randrepeat=1 --filename=./fio.test --size=10G --direct=1 --rw=randrw --bs=128k --ioengine=sync --iodepth=8 --iodepth_batch_submit=8 --numjobs=8 --group_reporting --name=iops-test-job --eta-newline=1 --rwmixread=75

iops-test-job: (g=0): rw=randrw, bs=(R) 128KiB-128KiB, (W) 128KiB-128KiB, (T) 128KiB-128KiB, ioengine=sync, iodepth=8
...
fio-3.27
Starting 8 processes
Jobs: 8 (f=8): [m(8)][26.7%][r=1538MiB/s,w=505MiB/s][r=12.3k,w=4040 IOPS][eta 00m:11s]
Jobs: 8 (f=8): [m(8)][27.3%][r=782MiB/s,w=269MiB/s][r=6254,w=2152 IOPS][eta 00m:16s]
Jobs: 8 (f=8): [m(8)][28.6%][r=800MiB/s,w=264MiB/s][r=6397,w=2111 IOPS][eta 00m:20s]
Jobs: 8 (f=8): [m(8)][30.3%][r=737MiB/s,w=261MiB/s][r=5892,w=2084 IOPS][eta 00m:23s]
Jobs: 8 (f=8): [m(8)][32.4%][r=791MiB/s,w=258MiB/s][r=6328,w=2061 IOPS][eta 00m:25s]
Jobs: 8 (f=8): [m(8)][35.0%][r=733MiB/s,w=243MiB/s][r=5863,w=1947 IOPS][eta 00m:26s]
Jobs: 8 (f=8): [m(8)][37.2%][r=896MiB/s,w=305MiB/s][r=7165,w=2443 IOPS][eta 00m:27s]
Jobs: 8 (f=8): [m(8)][40.0%][r=918MiB/s,w=307MiB/s][r=7341,w=2459 IOPS][eta 00m:27s]
Jobs: 8 (f=8): [m(8)][42.6%][r=602MiB/s,w=195MiB/s][r=4819,w=1560 IOPS][eta 00m:27s]
Jobs: 8 (f=8): [m(8)][44.9%][r=793MiB/s,w=269MiB/s][r=6343,w=2149 IOPS][eta 00m:27s]
Jobs: 8 (f=8): [m(8)][47.1%][r=821MiB/s,w=270MiB/s][r=6564,w=2163 IOPS][eta 00m:27s]
Jobs: 8 (f=8): [m(8)][50.0%][r=849MiB/s,w=292MiB/s][r=6791,w=2339 IOPS][eta 00m:26s]
Jobs: 8 (f=8): [m(8)][52.8%][r=926MiB/s,w=319MiB/s][r=7405,w=2552 IOPS][eta 00m:25s]
Jobs: 8 (f=8): [m(8)][55.6%][r=976MiB/s,w=325MiB/s][r=7808,w=2599 IOPS][eta 00m:24s]
Jobs: 8 (f=8): [m(8)][58.2%][r=899MiB/s,w=300MiB/s][r=7188,w=2403 IOPS][eta 00m:23s]
Jobs: 8 (f=8): [m(8)][60.7%][r=531MiB/s,w=174MiB/s][r=4250,w=1394 IOPS][eta 00m:22s]
Jobs: 8 (f=8): [m(8)][62.1%][r=594MiB/s,w=203MiB/s][r=4753,w=1622 IOPS][eta 00m:22s]
Jobs: 8 (f=8): [m(8)][64.4%][r=677MiB/s,w=224MiB/s][r=5419,w=1792 IOPS][eta 00m:21s]
Jobs: 8 (f=8): [m(8)][66.7%][r=729MiB/s,w=230MiB/s][r=5831,w=1841 IOPS][eta 00m:20s]
Jobs: 8 (f=8): [m(8)][68.9%][r=687MiB/s,w=243MiB/s][r=5493,w=1942 IOPS][eta 00m:19s]
Jobs: 8 (f=8): [m(8)][71.0%][r=801MiB/s,w=273MiB/s][r=6406,w=2183 IOPS][eta 00m:18s]
Jobs: 8 (f=8): [m(8)][74.2%][r=898MiB/s,w=297MiB/s][r=7185,w=2375 IOPS][eta 00m:16s]
Jobs: 8 (f=8): [m(8)][77.4%][r=818MiB/s,w=269MiB/s][r=6546,w=2153 IOPS][eta 00m:14s]
Jobs: 8 (f=8): [m(8)][79.4%][r=675MiB/s,w=222MiB/s][r=5401,w=1773 IOPS][eta 00m:13s]
Jobs: 8 (f=8): [m(8)][81.2%][r=702MiB/s,w=232MiB/s][r=5619,w=1854 IOPS][eta 00m:12s]
Jobs: 8 (f=8): [m(8)][83.1%][r=683MiB/s,w=235MiB/s][r=5463,w=1882 IOPS][eta 00m:11s]
Jobs: 8 (f=8): [m(8)][86.2%][r=808MiB/s,w=270MiB/s][r=6466,w=2162 IOPS][eta 00m:09s]
Jobs: 8 (f=8): [m(8)][89.2%][r=770MiB/s,w=252MiB/s][r=6160,w=2014 IOPS][eta 00m:07s]
Jobs: 8 (f=8): [m(8)][90.9%][r=805MiB/s,w=272MiB/s][r=6436,w=2174 IOPS][eta 00m:06s]
Jobs: 8 (f=8): [m(8)][93.9%][r=838MiB/s,w=284MiB/s][r=6701,w=2271 IOPS][eta 00m:04s]
Jobs: 8 (f=8): [m(8)][97.0%][r=1017MiB/s,w=335MiB/s][r=8137,w=2680 IOPS][eta 00m:02s]
Jobs: 1 (f=1): [(3),m(1),(4)][100.0%][r=817MiB/s,w=257MiB/s][r=6539,w=2053 IOPS][eta 00m:00s]
iops-test-job: (groupid=0, jobs=8): err= 0: pid=22448: Wed Dec 29 17:28:47 2021
read: IOPS=7681, BW=960MiB/s (1007MB/s)(60.0GiB/63986msec)
clat (usec): min=3, max=31324, avg=23.72, stdev=158.94
lat (usec): min=3, max=31324, avg=23.76, stdev=158.94
clat percentiles (usec):
| 1.00th=[ 7], 5.00th=[ 7], 10.00th=[ 8], 20.00th=[ 14],
| 30.00th=[ 15], 40.00th=[ 16], 50.00th=[ 16], 60.00th=[ 17],
| 70.00th=[ 17], 80.00th=[ 19], 90.00th=[ 38], 95.00th=[ 67],
| 99.00th=[ 105], 99.50th=[ 119], 99.90th=[ 635], 99.95th=[ 1745],
| 99.99th=[ 7373]
bw ( KiB/s): min=484096, max=10253199, per=100.00%, avg=984672.14, stdev=141259.34, samples=1010
iops : min= 3782, max=80100, avg=7692.66, stdev=1103.55, samples=1010
write: IOPS=2560, BW=320MiB/s (336MB/s)(20.0GiB/63986msec); 0 zone resets
clat (usec): min=12, max=38277, avg=3025.59, stdev=1507.55
lat (usec): min=12, max=38278, avg=3026.06, stdev=1507.34
clat percentiles (usec):
| 1.00th=[ 20], 5.00th=[ 36], 10.00th=[ 61], 20.00th=[ 1663],
| 30.00th=[ 3064], 40.00th=[ 3261], 50.00th=[ 3458], 60.00th=[ 3654],
| 70.00th=[ 3818], 80.00th=[ 4015], 90.00th=[ 4490], 95.00th=[ 4883],
| 99.00th=[ 5473], 99.50th=[ 5735], 99.90th=[ 6128], 99.95th=[ 6390],
| 99.99th=[ 6915]
bw ( KiB/s): min=174848, max=3511655, per=100.00%, avg=328313.31, stdev=47484.87, samples=1010
iops : min= 1366, max=27431, avg=2564.87, stdev=370.94, samples=1010
lat (usec) : 4=0.01%, 10=14.41%, 20=48.19%, 50=8.27%, 100=6.59%
lat (usec) : 250=1.13%, 500=0.19%, 750=0.23%, 1000=0.20%
lat (msec) : 2=1.13%, 4=14.33%, 10=5.33%, 20=0.01%, 50=0.01%
cpu : usr=0.14%, sys=2.60%, ctx=149825, majf=0, minf=137
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 rwts: total=491539,163821,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=8

Run status group 0 (all jobs):
READ: bw=960MiB/s (1007MB/s), 960MiB/s-960MiB/s (1007MB/s-1007MB/s), io=60.0GiB (64.4GB), run=63986-63986msec
WRITE: bw=320MiB/s (336MB/s), 320MiB/s-320MiB/s (336MB/s-336MB/s), io=20.0GiB (21.5GB), run=63986-63986msec

fio --randrepeat=1 --filename=./fio.test --size=10G --direct=1 --rw=randrw --bs=256k --ioengine=sync --iodepth=8 --iodepth_batch_submit=8 --numjobs=8 --group_reporting --name=iops-test-job --eta-newline=1 --rwmixread=75


iops-test-job: (g=0): rw=randrw, bs=(R) 256KiB-256KiB, (W) 256KiB-256KiB, (T) 256KiB-256KiB, ioengine=sync, iodepth=8...
fio-3.27
Starting 8 processes
Jobs: 8 (f=8): [m(8)][25.0%][r=1495MiB/s,w=514MiB/s][r=5981,w=2056 IOPS][eta 00m:12s]
Jobs: 8 (f=8): [m(8)][26.1%][r=769MiB/s,w=253MiB/s][r=3075,w=1013 IOPS][eta 00m:17s]
Jobs: 8 (f=8): [m(8)][28.6%][r=1011MiB/s,w=326MiB/s][r=4045,w=1302 IOPS][eta 00m:20s]
Jobs: 8 (f=8): [m(8)][32.3%][r=1133MiB/s,w=373MiB/s][r=4530,w=1491 IOPS][eta 00m:21s]
Jobs: 8 (f=8): [m(8)][35.3%][r=1115MiB/s,w=366MiB/s][r=4460,w=1464 IOPS][eta 00m:22s]
Jobs: 8 (f=8): [m(8)][38.9%][r=1304MiB/s,w=425MiB/s][r=5214,w=1700 IOPS][eta 00m:22s]
Jobs: 8 (f=8): [m(8)][42.1%][r=853MiB/s,w=286MiB/s][r=3410,w=1144 IOPS][eta 00m:22s]
Jobs: 8 (f=8): [m(8)][45.0%][r=781MiB/s,w=268MiB/s][r=3124,w=1070 IOPS][eta 00m:22s]
Jobs: 8 (f=8): [m(8)][47.6%][r=874MiB/s,w=290MiB/s][r=3494,w=1160 IOPS][eta 00m:22s]
Jobs: 8 (f=8): [m(8)][50.0%][r=960MiB/s,w=346MiB/s][r=3840,w=1383 IOPS][eta 00m:22s]
Jobs: 8 (f=8): [m(8)][53.3%][r=933MiB/s,w=313MiB/s][r=3733,w=1252 IOPS][eta 00m:21s]
Jobs: 8 (f=8): [m(8)][56.5%][r=1110MiB/s,w=358MiB/s][r=4441,w=1432 IOPS][eta 00m:20s]
Jobs: 8 (f=8): [m(8)][60.9%][r=1056MiB/s,w=364MiB/s][r=4224,w=1454 IOPS][eta 00m:18s]
Jobs: 8 (f=8): [m(8)][63.8%][r=943MiB/s,w=301MiB/s][r=3771,w=1204 IOPS][eta 00m:17s]
Jobs: 8 (f=8): [m(8)][66.7%][r=1074MiB/s,w=349MiB/s][r=4294,w=1395 IOPS][eta 00m:16s]
Jobs: 8 (f=8): [m(8)][69.4%][r=984MiB/s,w=331MiB/s][r=3937,w=1322 IOPS][eta 00m:15s]
Jobs: 8 (f=8): [m(8)][72.0%][r=851MiB/s,w=287MiB/s][r=3402,w=1149 IOPS][eta 00m:14s]
Jobs: 8 (f=8): [m(8)][76.0%][r=920MiB/s,w=321MiB/s][r=3679,w=1284 IOPS][eta 00m:12s]
Jobs: 8 (f=8): [m(8)][78.4%][r=1050MiB/s,w=328MiB/s][r=4198,w=1313 IOPS][eta 00m:11s]
Jobs: 8 (f=8): [m(8)][80.8%][r=570MiB/s,w=196MiB/s][r=2280,w=783 IOPS][eta 00m:10s]
Jobs: 8 (f=8): [m(8)][83.0%][r=784MiB/s,w=263MiB/s][r=3135,w=1052 IOPS][eta 00m:09s]
Jobs: 8 (f=8): [m(8)][86.8%][r=919MiB/s,w=318MiB/s][r=3676,w=1271 IOPS][eta 00m:07s]
Jobs: 8 (f=8): [m(8)][88.9%][r=884MiB/s,w=291MiB/s][r=3535,w=1165 IOPS][eta 00m:06s]
Jobs: 8 (f=8): [m(8)][92.6%][r=1031MiB/s,w=325MiB/s][r=4124,w=1300 IOPS][eta 00m:04s]
Jobs: 8 (f=8): [m(8)][94.5%][r=1090MiB/s,w=372MiB/s][r=4361,w=1489 IOPS][eta 00m:03s]
Jobs: 7 (f=7): [m(6),(1),m(1)][98.2%][r=803MiB/s,w=290MiB/s][r=3213,w=1159 IOPS][eta 00m:01s] Jobs: 2 (f=2): [m(1),(2),m(1),_(4)][100.0%][r=670MiB/s,w=224MiB/s][r=2680,w=894 IOPS][eta 00m:00s]
iops-test-job: (groupid=0, jobs=8): err= 0: pid=12791: Wed Dec 29 17:27:10 2021
read: IOPS=4544, BW=1136MiB/s (1191MB/s)(59.9GiB/54009msec)
clat (usec): min=6, max=37703, avg=46.85, stdev=211.13
lat (usec): min=6, max=37703, avg=46.91, stdev=211.13
clat percentiles (usec):
| 1.00th=[ 13], 5.00th=[ 14], 10.00th=[ 14], 20.00th=[ 27],
| 30.00th=[ 30], 40.00th=[ 31], 50.00th=[ 32], 60.00th=[ 33],
| 70.00th=[ 34], 80.00th=[ 38], 90.00th=[ 77], 95.00th=[ 137],
| 99.00th=[ 221], 99.50th=[ 255], 99.90th=[ 1582], 99.95th=[ 3163],
| 99.99th=[ 9241]
bw ( MiB/s): min= 494, max= 9652, per=100.00%, avg=1144.48, stdev=144.33, samples=852
iops : min= 1978, max=38607, avg=4577.88, stdev=577.29, samples=852
write: IOPS=1522, BW=381MiB/s (399MB/s)(20.1GiB/54009msec); 0 zone resets
clat (usec): min=20, max=27805, avg=5063.57, stdev=2444.92
lat (usec): min=21, max=27807, avg=5064.76, stdev=2444.10
clat percentiles (usec):
| 1.00th=[ 42], 5.00th=[ 85], 10.00th=[ 125], 20.00th=[ 3589],
| 30.00th=[ 5080], 40.00th=[ 5407], 50.00th=[ 5669], 60.00th=[ 5997],
| 70.00th=[ 6390], 80.00th=[ 6718], 90.00th=[ 7373], 95.00th=[ 7898],
| 99.00th=[ 9372], 99.50th=[10552], 99.90th=[11469], 99.95th=[11600],
| 99.99th=[12518]
bw ( KiB/s): min=184832, max=3352134, per=100.00%, avg=392700.39, stdev=50158.90, samples=852
iops : min= 722, max=13093, avg=1533.96, stdev=195.91, samples=852
lat (usec) : 10=0.01%, 20=13.73%, 50=51.47%, 100=5.20%, 250=7.47%
lat (usec) : 500=0.41%, 750=0.13%, 1000=0.11%
lat (msec) : 2=0.50%, 4=1.14%, 10=19.63%, 20=0.19%, 50=0.01%
cpu : usr=0.12%, sys=3.07%, ctx=151268, majf=0, minf=133
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 rwts: total=245434,82246,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=8

Run status group 0 (all jobs):
READ: bw=1136MiB/s (1191MB/s), 1136MiB/s-1136MiB/s (1191MB/s-1191MB/s), io=59.9GiB (64.3GB), run=54009-54009msec
WRITE: bw=381MiB/s (399MB/s), 381MiB/s-381MiB/s (399MB/s-399MB/s), io=20.1GiB (21.6GB), run=54009-54009msec

А теперь внимание 4к блок:

fio --randrepeat=1 --filename=./fio.test --size=10G --direct=1 --rw=randrw --bs=4k --ioengine=sync --iodepth=8 --iodepth_batch_submit=8 --numjobs=8 --group_reporting --name=iops-test-job --eta-newline=1 --rwmixread=75

iops-test-job: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=sync, iodepth=8
...
fio-3.27
Starting 8 processes
Jobs: 8 (f=8): [m(8)][0.9%][r=46.0MiB/s,w=15.5MiB/s][r=11.8k,w=3956 IOPS][eta 07m:41s]
Jobs: 8 (f=8): [m(8)][0.9%][r=26.9MiB/s,w=9784KiB/s][r=6877,w=2446 IOPS][eta 11m:09s]
Jobs: 8 (f=8): [m(8)][1.0%][r=31.5MiB/s,w=10.6MiB/s][r=8060,w=2703 IOPS][eta 13m:49s]
Jobs: 8 (f=8): [m(8)][1.0%][r=28.4MiB/s,w=9480KiB/s][r=7269,w=2370 IOPS][eta 15m:57s]
Jobs: 8 (f=8): [m(8)][1.1%][r=28.9MiB/s,w=9780KiB/s][r=7388,w=2445 IOPS][eta 17m:43s]
Jobs: 8 (f=8): [m(8)][1.2%][r=31.9MiB/s,w=10.9MiB/s][r=8166,w=2780 IOPS][eta 19m:01s]

......
Jobs: 8 (f=8): [m(8)][98.8%][r=26.5MiB/s,w=9120KiB/s][r=6779,w=2280 IOPS][eta 00m:30s]
Jobs: 8 (f=8): [m(8)][98.9%][r=23.3MiB/s,w=7696KiB/s][r=5964,w=1924 IOPS][eta 00m:28s]
Jobs: 8 (f=8): [m(8)][99.0%][r=24.1MiB/s,w=8760KiB/s][r=6170,w=2190 IOPS][eta 00m:26s]
Jobs: 8 (f=8): [m(8)][99.1%][r=26.3MiB/s,w=8936KiB/s][r=6725,w=2234 IOPS][eta 00m:24s]
Jobs: 8 (f=8): [m(8)][99.1%][r=28.9MiB/s,w=9704KiB/s][r=7400,w=2426 IOPS][eta 00m:22s]
Jobs: 8 (f=8): [m(8)][99.3%][r=30.8MiB/s,w=10.3MiB/s][r=7895,w=2627 IOPS][eta 00m:19s]
Jobs: 8 (f=8): [m(8)][99.4%][r=34.2MiB/s,w=11.6MiB/s][r=8745,w=2979 IOPS][eta 00m:16s]
Jobs: 8 (f=8): [m(8)][99.5%][r=36.7MiB/s,w=12.2MiB/s][r=9396,w=3132 IOPS][eta 00m:13s]
Jobs: 8 (f=8): [m(8)][99.6%][r=23.4MiB/s,w=7704KiB/s][r=5986,w=1926 IOPS][eta 00m:11s]
Jobs: 8 (f=8): [m(8)][99.7%][r=29.0MiB/s,w=9.96MiB/s][r=7412,w=2550 IOPS][eta 00m:09s]
Jobs: 8 (f=8): [m(8)][99.8%][r=30.1MiB/s,w=9872KiB/s][r=7709,w=2468 IOPS][eta 00m:06s]
Jobs: 8 (f=8): [m(8)][99.8%][r=25.1MiB/s,w=8844KiB/s][r=6427,w=2211 IOPS][eta 00m:04s]
Jobs: 3 (f=3): [m(2),_(5),m(1)][100.0%][r=34.5MiB/s,w=10.9MiB/s][r=8827,w=2782 IOPS][eta 00m:00s]
iops-test-job: (groupid=0, jobs=8): err= 0: pid=24292: Wed Dec 29 18:21:34 2021
read: IOPS=6113, BW=23.9MiB/s (25.0MB/s)(60.0GiB/2572268msec)
clat (nsec): min=740, max=53590k, avg=10697.23, stdev=33246.32
lat (nsec): min=760, max=53590k, avg=10742.76, stdev=33246.96
clat percentiles (nsec):
| 1.00th=[ 1464], 5.00th=[ 1608], 10.00th=[ 1704], 20.00th=[ 1992],
| 30.00th=[ 11584], 40.00th=[ 12608], 50.00th=[ 12992], 60.00th=[ 13376],
| 70.00th=[ 13760], 80.00th=[ 14144], 90.00th=[ 15040], 95.00th=[ 15936],
| 99.00th=[ 20352], 99.50th=[ 24192], 99.90th=[ 79360], 99.95th=[ 95744],
| 99.99th=[123392]
bw ( KiB/s): min= 9304, max=314495, per=100.00%, avg=24455.63, stdev=938.24, samples=41127
iops : min= 2326, max=78621, avg=6113.84, stdev=234.56, samples=41127
write: IOPS=2038, BW=8156KiB/s (8352kB/s)(20.0GiB/2572268msec); 0 zone resets
clat (usec): min=3, max=36815, avg=3888.22, stdev=786.33
lat (usec): min=3, max=36815, avg=3888.30, stdev=786.33
clat percentiles (usec):
| 1.00th=[ 2409], 5.00th=[ 2835], 10.00th=[ 3032], 20.00th=[ 3261],
| 30.00th=[ 3458], 40.00th=[ 3654], 50.00th=[ 3851], 60.00th=[ 4015],
| 70.00th=[ 4228], 80.00th=[ 4424], 90.00th=[ 4817], 95.00th=[ 5211],
| 99.00th=[ 6063], 99.50th=[ 6325], 99.90th=[ 7373], 99.95th=[ 7701],
| 99.99th=[ 8455]
bw ( KiB/s): min= 3864, max=106361, per=99.99%, avg=8155.80, stdev=296.32, samples=41127
iops : min= 966, max=26589, avg=2038.88, stdev=74.08, samples=41127
lat (nsec) : 750=0.01%, 1000=0.04%
lat (usec) : 2=15.02%, 4=5.93%, 10=0.13%, 20=53.06%, 50=0.68%
lat (usec) : 100=0.19%, 250=0.05%, 500=0.01%, 750=0.01%, 1000=0.01%
lat (msec) : 2=0.04%, 4=14.49%, 10=10.35%, 20=0.01%, 50=0.01%
lat (msec) : 100=0.01%
cpu : usr=0.08%, sys=1.21%, ctx=5246713, majf=0, minf=146
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 rwts: total=15726772,5244748,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=8

Run status group 0 (all jobs):
READ: bw=23.9MiB/s (25.0MB/s), 23.9MiB/s-23.9MiB/s (25.0MB/s-25.0MB/s), io=60.0GiB (64.4GB), run=2572268-2572268msec
WRITE: bw=8156KiB/s (8352kB/s), 8156KiB/s-8156KiB/s (8352kB/s-8352kB/s), io=20.0GiB (21.5GB), run=2572268-2572268msec

Удручающая картина, не правда ли? А теперь внимание, то-же самое для NVME

NVME> fio --randrepeat=1 --filename=./fio.test --size=10G --direct=1 --rw=randrw --bs=4k --ioengine=sync --iodepth=8 --iodepth_batch_submit=8 --numjobs=8 --group_reporting --name=iops-test-job --eta-newline=1 --rwmixread=75

iops-test-job: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=sync, iodepth=8
...
fio-3.27
Starting 8 processes
iops-test-job: Laying out IO file (1 file / 10240MiB)
Jobs: 8 (f=8): [m(8)][4.1%][r=657MiB/s,w=217MiB/s][r=168k,w=55.7k IOPS][eta 01m:33s]
........

Jobs: 8 (f=8): [m(8)][96.8%][r=657MiB/s,w=220MiB/s][r=168k,w=56.3k IOPS][eta 00m:03s]
Jobs: 8 (f=8): [m(8)][98.9%][r=657MiB/s,w=217MiB/s][r=168k,w=55.6k IOPS][eta 00m:01s]
Jobs: 8 (f=8): [m(8)][100.0%][r=653MiB/s,w=219MiB/s][r=167k,w=56.0k IOPS][eta 00m:00s]
iops-test-job: (groupid=0, jobs=8): err= 0: pid=22788: Wed Dec 29 19:02:39 2021
read: IOPS=167k, BW=654MiB/s (685MB/s)(60.0GiB/93995msec)
clat (usec): min=17, max=8563, avg=43.77, stdev=30.11
lat (usec): min=17, max=8564, avg=43.80, stdev=30.11
clat percentiles (usec):
| 1.00th=[ 38], 5.00th=[ 38], 10.00th=[ 38], 20.00th=[ 39],
| 30.00th=[ 40], 40.00th=[ 40], 50.00th=[ 40], 60.00th=[ 41],
| 70.00th=[ 41], 80.00th=[ 43], 90.00th=[ 49], 95.00th=[ 63],
| 99.00th=[ 135], 99.50th=[ 157], 99.90th=[ 176], 99.95th=[ 184],
| 99.99th=[ 297]
bw ( KiB/s): min=635320, max=681120, per=100.00%, avg=669528.73, stdev=1143.75, samples=1496
iops : min=158830, max=170280, avg=167382.17, stdev=285.94, samples=1496
write: IOPS=55.8k, BW=218MiB/s (229MB/s)(20.0GiB/93995msec); 0 zone resets
clat (usec): min=9, max=8514, avg=10.45, stdev= 5.40
lat (usec): min=9, max=8515, avg=10.50, stdev= 5.40
clat percentiles (nsec):
| 1.00th=[ 9664], 5.00th=[ 9792], 10.00th=[ 9792], 20.00th=[ 9920],
| 30.00th=[ 9920], 40.00th=[10048], 50.00th=[10176], 60.00th=[10304],
| 70.00th=[10560], 80.00th=[10944], 90.00th=[11456], 95.00th=[11968],
| 99.00th=[13504], 99.50th=[14272], 99.90th=[15808], 99.95th=[16768],
| 99.99th=[19584]
bw ( KiB/s): min=207440, max=235672, per=100.00%, avg=223287.40, stdev=627.87, samples=1496
iops : min=51860, max=58918, avg=55821.85, stdev=156.97, samples=1496
lat (usec) : 10=8.24%, 20=16.77%, 50=67.79%, 100=5.81%, 250=1.38%
lat (usec) : 500=0.01%, 750=0.01%, 1000=0.01%
lat (msec) : 2=0.01%, 4=0.01%, 10=0.01%
cpu : usr=1.70%, sys=4.07%, ctx=20977179, majf=0, minf=126
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 rwts: total=15726772,5244748,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=8

Run status group 0 (all jobs):
READ: bw=654MiB/s (685MB/s), 654MiB/s-654MiB/s (685MB/s-685MB/s), io=60.0GiB (64.4GB), run=93995-93995msec
WRITE: bw=218MiB/s (229MB/s), 218MiB/s-218MiB/s (229MB/s-229MB/s), io=20.0GiB (21.5GB), run=93995-93995msec

Disk stats (read/write):
nvme0n1: ios=15717227/5241742, merge=0/2, ticks=667570/47502, in_queue=715089, util=99.91%

NVME выдаёт 220к 4к IOPS в сумме (r+w). При этом Samsung заявляет о 1М IOPS.Видимо не 4К IOPS.

В общем врут. Вернее "грамотно преподносят информацию".

Тесты ZFS могут не говорить о реальной призводительности если неизвестно сколько памяти получил ARC — ZFS очень агрессивен в кэшировании (direct i/o игнорирует), так что если памяти у вас достаточно (32GB или больше) вы меряете производительность самой файловой системы, а не накопителя. Поставьте ограничение на ARC чтобы файл в него точно не влезал, и добавьте --fsync=1 к fio (убедившись что в ZFS не стоит sync=disabled) — тогда тест будет более реалистичным.


С блоками по 4k ситуация очень плохая за счёт организации самого ZFS (дерево, контрольные суммы и вот это всё) — сделайте ramdisk и померяйте, результаты тоже будут не впечатляющими, хотя конечно лучше чем с диском (любым).


NVME выдаёт 220к 4к IOPS в сумме (r+w). При этом Samsung заявляет о 1М IOPS.Видимо не 4К IOPS.

Потому что они указывают данные не для микса, а отдельно для чтения и записи — на только чтении или записи вы вероятно можете получить почти близко к 1M iops при QD > 32 а то и 128, правда, в вакууме идеальных условиях — т.е. тестируете его в монопольном режиме, причём заточенным под максимум производительности тулом. Вообще странно было бы ожидать от производителя гарантии iops не зная где и как будет использоваться накопитель, может его вообще по USB подключат, поэтому они указывают возможности железа (NVMe + PCIe), а вытянет ли их ваш конкретный сетап — это уже вопрос.


Теперь вернёмся к NVMe на Hetzner. Я провел тот же тест с файлом в 20G, с блоками по 1M и 4k, всё длительностью 1 минута — думаю это уж точно в кэш не влезло (разве что в SLC на самом накопителе):


fio --filename=/fio.test --size=20G --direct=1 --rw=randrw --bs=1m --ioengine=libaio --iodepth=8 --iodepth_batch_submit=8 --runtime=60 --numjobs=6 --time_based --group_reporting --name=iops-test-job --eta-newline=10
Jobs: 6 (f=6): [m(6)][20.0%][r=2672MiB/s,w=2636MiB/s][r=2672,w=2636 IOPS][eta 00m:48s]
Jobs: 6 (f=6): [m(6)][38.3%][r=2862MiB/s,w=2910MiB/s][r=2862,w=2910 IOPS][eta 00m:37s]
Jobs: 6 (f=6): [m(6)][56.7%][r=2854MiB/s,w=2893MiB/s][r=2854,w=2893 IOPS][eta 00m:26s]
Jobs: 6 (f=6): [m(6)][75.0%][r=2758MiB/s,w=2820MiB/s][r=2757,w=2819 IOPS][eta 00m:15s]
Jobs: 6 (f=6): [m(6)][93.3%][r=2850MiB/s,w=2865MiB/s][r=2850,w=2865 IOPS][eta 00m:04s]
Jobs: 6 (f=6): [m(6)][100.0%][r=2745MiB/s,w=2703MiB/s][r=2744,w=2702 IOPS][eta 00m:00s]
iops-test-job: (groupid=0, jobs=6): err= 0: pid=415743: Wed Dec 29 22:20:30 2021
  read: IOPS=2791, BW=2792MiB/s (2927MB/s)(164GiB/60006msec)

Разумеется, если я снижаюсь до 4k, то получаем сильное проседание по bandwidth, но если учесть что это виртуалка и на одном хосте их много, то оверхед и общая нагрузка сильно портят картину:


# fio --filename=/fio.test --size=20G --direct=1 --rw=randrw --bs=4k --ioengine=libaio --iodepth=8 --iodepth_batch_submit=8 --runtime=60 --numjobs=6 --time_based --group_reporting --name=iops-test-job --eta-newline=10
Jobs: 6 (f=6): [m(6)][20.0%][r=96.8MiB/s,w=97.9MiB/s][r=24.8k,w=25.1k IOPS][eta 00m:48s]
Jobs: 6 (f=6): [m(6)][38.3%][r=98.9MiB/s,w=99.9MiB/s][r=25.3k,w=25.6k IOPS][eta 00m:37s]
Jobs: 6 (f=6): [m(6)][56.7%][r=99.7MiB/s,w=99.7MiB/s][r=25.5k,w=25.5k IOPS][eta 00m:26s]
Jobs: 6 (f=6): [m(6)][75.0%][r=111MiB/s,w=111MiB/s][r=28.4k,w=28.3k IOPS][eta 00m:15s]
Jobs: 6 (f=6): [m(6)][93.3%][r=107MiB/s,w=106MiB/s][r=27.3k,w=27.2k IOPS][eta 00m:04s]
Jobs: 6 (f=6): [m(6)][100.0%][r=105MiB/s,w=105MiB/s][r=26.8k,w=26.8k IOPS][eta 00m:00s]
iops-test-job: (groupid=0, jobs=6): err= 0: pid=415775: Wed Dec 29 22:29:51 2021
  read: IOPS=26.2k, BW=102MiB/s (107MB/s)(6134MiB/60002msec)

Очевидно что результаты, как вы выразились, "не впечатляющие", но если туда поставить обычные (не NVMe) SSD, они станут в несколько раз менее впечатляющими, а если учесть любовь некоторых хостеров строить хосты на ZFS, то всё совсем может оказаться печально (принудительный COW даже на блочных устройствах, компрессия и прочие радости — зато типа "супер надёжно").


Для сравнения — вот результат от OVH (VPS Comfort), где они тоже пишут про NVMe:


fio --filename=/fio.test --size=20G --direct=1 --rw=randrw --bs=4k --ioengine=libaio --iodepth=8 --iodepth_batch_submit=8 --runtime=60 --numjobs=6 --time_based --group_reporting --name=iops-test-job --eta-newline=10
Jobs: 6 (f=6): [m(6)][18.3%][r=60.8MiB/s,w=61.6MiB/s][r=15.6k,w=15.8k IOPS][eta 00m:49s]
Jobs: 6 (f=6): [m(6)][36.1%][r=63.4MiB/s,w=62.5MiB/s][r=16.2k,w=16.0k IOPS][eta 00m:39s]
Jobs: 6 (f=6): [m(6)][52.5%][r=62.7MiB/s,w=62.5MiB/s][r=16.0k,w=16.0k IOPS][eta 00m:29s]
Jobs: 6 (f=6): [m(6)][68.9%][r=61.9MiB/s,w=62.5MiB/s][r=15.8k,w=16.0k IOPS][eta 00m:19s]
Jobs: 6 (f=6): [m(6)][85.2%][r=61.0MiB/s,w=62.5MiB/s][r=15.9k,w=16.0k IOPS][eta 00m:09s]
Jobs: 6 (f=6): [m(6)][100.0%][r=63.0MiB/s,w=62.5MiB/s][r=16.1k,w=16.0k IOPS][eta 00m:00s]
iops-test-job: (groupid=0, jobs=6): err= 0: pid=3963560: Wed Dec 29 22:11:02 2021
  read: IOPS=15.0k, BW=62.4MiB/s (65.4MB/s)(3743MiB/60003msec)

Очень похоже что что они ограничивают iops до 16k (слишком ровные результаты), соответственно при блоках в 4k сильно проседает и bandwidth. То же самое для 1M:


fio --filename=/fio.test --size=20G --direct=1 --rw=randrw --bs=1m --ioengine=libaio --iodepth=8 --iodepth_batch_submit=8 --runtime=60 --numjobs=6 --time_based --group_reporting --name=iops-test-job --eta-newline=10
Jobs: 6 (f=6): [m(6)][19.7%][r=1048MiB/s,w=1055MiB/s][r=1047,w=1054 IOPS][eta 00m:49s]
Jobs: 6 (f=6): [m(6)][36.1%][r=979MiB/s,w=940MiB/s][r=979,w=940 IOPS][eta 00m:39s]
Jobs: 6 (f=6): [m(6)][52.5%][r=1052MiB/s,w=961MiB/s][r=1051,w=961 IOPS][eta 00m:29s]
Jobs: 6 (f=6): [m(6)][68.9%][r=1057MiB/s,w=961MiB/s][r=1056,w=961 IOPS][eta 00m:19s]
Jobs: 6 (f=6): [m(6)][85.2%][r=1059MiB/s,w=1006MiB/s][r=1058,w=1005 IOPS][eta 00m:09s]
Jobs: 6 (f=2): [f(1),m(1),f(3),m(1)][96.8%][r=973MiB/s,w=1050MiB/s][r=973,w=1049 IOPS][eta 00m:02s]
iops-test-job: (groupid=0, jobs=6): err= 0: pid=3963793: Wed Dec 29 22:13:57 2021
  read: IOPS=1000, BW=1000MiB/s (1049MB/s)(58.7GiB/60036msec)

Тут уже видно что идёт ограничение по bandwitdh (слишком уж "ровно" оно на протяжении всего теста) — и это в два-три раза менее впечатляюще чем у Hetzner.


Собственно, я и тесты-то сделал не чтобы показать что в виртуалке можно получить максимум от NVMe — за счёт виртуализации это практически невозможно (очень большой оверхед по дороге к накопителю, особенно если виртуалок много), но использование NVMe вполне оправданно — потому что без них всё будет намного хуже, как минимум в разы, а на загруженных по i/o хостах может даже на один-два порядка — по той простой причине что условные 500K iops на NVMe дадут по 50k iops на десяти виртуалках, в то время как не менее реалистичные 100k на "обычных" SSD дадут соответственно по 10k, да и скорость поделится соответственно.


В качестве иллюстрации оверхеда (домашний сервер, PNY CS3030 1T как накопитель, KVM в proxmox), на этот раз на чтении:


fio --filename=/dev/sda --size=20G --direct=1 --rw=randread --bs=4k --ioengine=libaio --iodepth=8 --iodepth_batch_submit=8 --runtime=60 --numjobs=6 --time_based --group_reporting --name=iops-test-job --eta-newline=10 --readonly
Jobs: 6 (f=6): [r(6)][20.0%][r=592MiB/s,w=0KiB/s][r=152k,w=0 IOPS][eta 00m:48s]
Jobs: 6 (f=6): [r(6)][38.3%][r=591MiB/s,w=0KiB/s][r=151k,w=0 IOPS][eta 00m:37s]
Jobs: 6 (f=6): [r(6)][56.7%][r=588MiB/s,w=0KiB/s][r=150k,w=0 IOPS][eta 00m:26s]
Jobs: 6 (f=6): [r(6)][75.0%][r=596MiB/s,w=0KiB/s][r=152k,w=0 IOPS][eta 00m:15s]
Jobs: 6 (f=6): [r(6)][93.3%][r=595MiB/s,w=0KiB/s][r=152k,w=0 IOPS][eta 00m:04s]
Jobs: 6 (f=6): [r(6)][100.0%][r=596MiB/s,w=0KiB/s][r=152k,w=0 IOPS][eta 00m:00s]
iops-test-job: (groupid=0, jobs=6): err= 0: pid=15829: Wed Dec 29 22:44:38 2021
   read: IOPS=150k, BW=586MiB/s (614MB/s)(34.3GiB/60001msec)

Это гораздо более впечатляюще чем у Hetzner, но — это сервер на котором нет нагрузки, он фактически простаивает, да и процессор на нём в пару раз пошустрее (а он важен для пути накопитель=>lvm=>vm и обратно). Теперь тот же fio на хосте через LVM который подцеплен к виртуалке:


fio --filename=/dev/mapper/npve-vm--222--disk--0 --size=20G --direct=1 --rw=randread --bs=4k --ioengine=libaio --iodepth=8 --iodepth_batch_submit=8 --runtime=60 --numjobs=6 --time_based --group_reporting --name=iops-test-job --eta-newline=10 --readonly
Jobs: 6 (f=6): [r(6)][19.7%][r=893MiB/s][r=229k IOPS][eta 00m:49s]
Jobs: 6 (f=6): [r(6)][36.1%][r=886MiB/s][r=227k IOPS][eta 00m:39s]
Jobs: 6 (f=6): [r(6)][54.1%][r=892MiB/s][r=228k IOPS][eta 00m:28s]
Jobs: 6 (f=6): [r(6)][72.1%][r=889MiB/s][r=228k IOPS][eta 00m:17s]
Jobs: 6 (f=6): [r(6)][90.2%][r=893MiB/s][r=229k IOPS][eta 00m:06s]
Jobs: 6 (f=6): [r(6)][100.0%][r=900MiB/s][r=231k IOPS][eta 00m:00s]
iops-test-job: (groupid=0, jobs=6): err= 0: pid=2993571: Wed Dec 29 22:46:47 2021
  read: IOPS=229k, BW=895MiB/s (938MB/s)(52.4GiB/60001msec)

Как видите, просто за счёт того что это виртуалка, мы уже теряем около 40%(!) — и это она одна, другой нагрузки в системе нет и даже отключены все митигации как на хосте так и на виртуалке (mitigations=off) — разумеется если виртуалок с десяток или два, они что-то делают, а поскольку это хостер то и митигации по полной программе — мы просядем ещё больше, но это проседание будет намного менее заметным чем в случае SATA/SAS.


Так что если кто-то говорит что "VPS получит скорость NVMe" — он скорее всего таки врёт, но если этот кто-то говорит "на наших хостах стоят NVMe и это сильно повышает производительность [чем если бы стояли SATA/SAS]" — то это всё же скорее всего правда — об этом говорит и опыт с хостерами, и собственный (правда, не на Hyper-V).


Про RAID для NVMe тоже смешанные чувства — конечно, "один раз не считается", но я для эксперимента делал softRAID1 (mdadm) на двух потребительских NVMe (PNY CS3030 1T, посаженных на один PCIe x16 слот в X470D4U + Ryzen 3600X), разницы в скорости практически не было (при записи), рандомное чтение было быстрее но не помню на сколько — и это совсем не серверное железо. Увы, это было относительно давно, сборки уже нет, а результаты я не сохранял — но успех этого эксперимента позволяет мне верить что заявленное Hetzner наличие RAID 10 на их cloud серверах очень реалистично, вопреки выводам в статье про невозможность (или нецелесообразность) RAID на NVMe.

А почему вы считаете что softRAID1 (mdadm) на двух потребительских NVMe должен давать увеличение производительности? Это ведь зеркало, оно надежность увеличивает. А производительность — та же, даже падает немного.

Человек хочет параллельного чтения с дисков при рейд 1. Кейсы где только чтение и в большом количестве существуют. Но для текущих вычислительных систем чтение 7гб/с (pcie4x4) для нвме практически нецелесообразно увеличивать. Гораздо лучше обеспечить горизонтальный рост, вместо вертикального.

Выполнил пример для Hetzner NVMe на Intel DC S3500 SATA, подключенным как JBOD через контроллер. Proxmox, ZFS, LXC, CentOS8.

fio --filename=/fio.test --size=20G --direct=1 --rw=randrw --bs=4k --ioengine=libaio --iodepth=8 --iodepth_batch_submit=8 --runtime=60 --numjobs=6 --time_based --group_reporting --name=iops-test-job --eta-newline=10

Результат в 3 раза ниже, чем у вас:

latency 31 мкс, IOPS 10k, bw 40 MB/s

Если бы вместо LXC был KVM, еще бы в 1.5-2 раза упало бы все.

Правда конечно бы на актуальных SSD сравнить c SATA и NVMe. Но похоже что да, есть смысл в NVMe.

З.Ы. При использовании Proxmox ZFS выбирают за бесплатные снапшоты с локальных дисков для контейнеров, а не за супернадежность.

На актуальных всё точно также — собственно, это и меня и сподвигло перейти на NVMe в своё время, это было небо и земля даже для чисто экспериментальных проектов с кучей VM (хотя изначально я тоже был скептически настроен).


Окрылённый полученным опытом я посоветовал давнему клиенту тоже попробовать (он периодически жаловался на производительность, несмотря на то что в системе были только SSD) — в итоге он остался доволен как слон и сказал что субъективно ощущения как после пересадки с HDD на (первые) SSD — хотя конечно это зависит от задач (у него сильно нагруженный i/o кластер с k8s).


Proxmox ZFS выбирают за бесплатные снапшоты

В чём их бесплатность по сравнению с LVM thin? Да и при любом раскладе это "бесплатно" только для хостера, для клиентов это боль если (к примеру) у них там нагруженные базы или ещё что-то чему вредит COW.


ZFS и так не быстрая, и лучшее ей применение это NAS & co, где данные редко модифицируются "по месту" (бэкапы и прочее), если её ставить на хостинг и там хорошая активность — это просто смерть производительности даже на NVMe, и это при выключенных компрессии и дедупликации, а с ними это вообще ужас-ужас — в начале всё ок но со временем за счёт фрагментации всё начинает тормозить просто ужасно, особенно если памяти на ARC не десятки гигабайт и процессор не очень многоядерный.


Также при тестах из ВМ есть риск, что чтение будет из ОЗУ хоста.

Риск есть только если хост принудительно включает кэш и игнорирует direct i/o — я очень сомневаюсь что Hetzner это делает, не говоря уже о том что это приводит к сильному "загрязнению" памяти хоста всяким мусором и в целом плохо сказывается на всех (любая VM может загнать в swap хост и сильно помешать соседям — объём кэша на процесс/пользователя не тюнится, разве что ядро патченное).


Но я делал тесты и по чтению, разумеется — результаты почти идентичны (разница в пару процентов).


Для полноты картину, вот результаты тестирования с /dev/ram0 (на той же VM):


# fio --filename=/dev/ram0 --size=1G --direct=1 --rw=randrw --bs=4k --ioengine=libaio --iodepth=8 --iodepth_batch_submit=8 --runtime=10 --numjobs=6 --time_based --group_reporting --name=iops-test-job --eta-newline=1
Jobs: 6 (f=6): [m(6)][30.0%][r=1307MiB/s,w=1315MiB/s][r=335k,w=337k IOPS][eta 00m:07s]
Jobs: 6 (f=6): [m(6)][50.0%][r=1256MiB/s,w=1258MiB/s][r=321k,w=322k IOPS][eta 00m:05s]
Jobs: 6 (f=6): [m(6)][70.0%][r=1244MiB/s,w=1243MiB/s][r=319k,w=318k IOPS][eta 00m:03s]
Jobs: 6 (f=6): [m(6)][90.0%][r=1188MiB/s,w=1185MiB/s][r=304k,w=303k IOPS][eta 00m:01s]
Jobs: 6 (f=6): [m(6)][100.0%][r=1326MiB/s,w=1329MiB/s][r=339k,w=340k IOPS][eta 00m:00s]
iops-test-job: (groupid=0, jobs=6): err= 0: pid=420764: Fri Dec 31 02:51:52 2021
  read: IOPS=323k, BW=1261MiB/s (1322MB/s)(12.3GiB/10001msec)

Так что очень маловероятно что хост кэширует что-то — даже с учётом оверхеда виртуализации это было в пусть в два-три раза медленней, но явно не на порядок.

В чём их бесплатность по сравнению с LVM thin? Да и при любом раскладе это "бесплатно" только для хостера, для клиентов это боль если (к примеру) у них там нагруженные базы или ещё что-то чему вредит COW.

В том, как ZFS внутри устроена. По сути, нужно лишь "форкнуть" дерево блоков. COW сделает все остальное.

Не сказал бы, что COW вредит базами. Наоборот. COW идеально сочетается с базами, т.к. они повсеместно пишут WAL. Что базы, что ZFS стараются не модифицировать то, что уже есть на диске. По крайней мере те базы, что были разработаны под HDD. По идее, если грамотно подобрать размер блока, то оверхед будет минимальный. Компрессия тут конечно немного жизнь подпортит. А уж про дедупликацию вообще надо забыть сразу. Никто ее не рекомендует использовать и поделом.

>Компрессия тут конечно немного жизнь подпортит

Компрессия наоборот "жизнь улучшит", т.к. сократит объём IO за счёт траты CPU ресурсов. Ну до тех пор пока CPU и ОЗУ хватает.

Это понятно, но из-за нее размер блока будет постоянно меняться и не будет четкого соответствия между тем, что пишет база, и что ложится на диски.

Это понятно, но из-за нее размер блока будет постоянно меняться и не будет четкого соответствия между тем, что пишет база, и что ложится на диски.

ashift=12 и в ZFS блок 4к, независимо от того сколько сжатой информации туда поместится. Для этого у ZFS свой scheduler.
Например БД 8к блок пишет и он поместился в 4к - идеальных вариант. И скорее всего будет сжат с каким нибудь дробным коэффициентом, и то-ли ~3КВ будет записано в блок, то-ли 1.5 блока ZFS будут использованы... Та ещё лотерея. Однако если смотреть на большие объёмы, - десятки и сотни ТБ, то эта лотерея в среднем будет идти только в плюс к производительности, чисто статистически. Т.е. например какая-нибудь БД с банковскими операциями будет в 2.5 раза сжата, а CDR в 10-11 раз. Это очень неплохой буст к скорости чтения.Лишь бы мощности ЦПУ хватило всё это распаковывать.

Если ashift=12 и recordsize/volblocksize=4K то будет работать только ZLE (сжатие нулей), потому как zfs не пишет сжатые блоки если они ужимаются меньше чем на 25% (пишет несжатый блок) и минимальный размер записи это 2^ashift. 2^12=4096, 4K.

Всё смешалось, кони,люди ...
Размер сектора zfs == 2^ashift. T.e. 2^12 = 4096.

И да, сжатые данные одной записи которые уместились в 3КБ будут целиком занимать 4КБ с ashift 12. А если БД оперирует 8кб или 32кб блоком, а ashift на ZFS 12, то шансы, что вы офигенно сэкономите на IOPS очень хорошие. И IO scheduler zfs в этом очень поможет.

Всё смешалось, кони, люди ...

Именно так )
БД может оперировать каким угодно блоком. Но если блок ФС равен 4К и она не использует для сжатия экстенты или иные группировки (для dataset это recordsize, для zvol — volblocksize; угадайте что случится, если вы их ограничите 4K) то, увы, ФС будет разбивать вашу 32K-запись в несколько 4K. И сжимать каждый блок отдельно.
UPD: А если вы сделаете их слишком большими, то получите потерю IOPS и вымывание ARC за счет множества RMW-циклов. Впрочем, add-only базы могут это и не заметить…

ФС будет разбивать вашу 32K-запись в несколько 4K. И сжимать каждый блок отдельно

Код с ZOL на эту тему в студию :)

Вы сейчас сказали, что компрессии не существует.
Я в коде такого не видел.
Видел: если запись идёт на 32к и сжимается с коэффициентом 3.2 , то будет уложена в 3х4к блока при ashift=12.

Edit:

ARC то здесь причём? Он к записи отношения не имеет.

Вы сейчас сказали, что компрессии не существует.

Нет. Всего лишь указал на некоторые тонкости, которые легко могут порушить wishful thinking.


ARC то здесь причём? Он к записи отношения не имеет.

RMW. Read-Modify-Write cycle. Оно, во-первых, по определению медленнее, чем просто Write — каджит надеется, что это хотя бы очевидно. Во-вторых, требует хранить больше данных в памяти для достижения того же результата.


Код с ZOL на эту тему в студию :)

Полноте, это вы теряете контекст и не понимаете, о чем идет идет речь. Вам и приводить доказательства, но сначала, прежде чем этот, все-таки, рекомендовал бы внимательно прочитать, о чем идет речь, и прочитать штатный хелп, или, хотя бы, этот профильный тред, прежде, чем укапываться в гит.
Потому как zpool allocation unit, zfs recordsize и zvol volblocksize — разные сущности. И все они совершенно ортогональны размеру блока, используемому каким-либо софтом.


Видел: если запись идёт на 32к и сжимается с коэффициентом 3.2, то будет уложена в 3х4к блока при ashift=12

Да. Если вы не ограничили сверху размер записи zfs (recordsize/volblocksize) равным размеру zpool ashift.
А теперь смотрите фокус:


ashift=12 и в ZFS блок 4к

Вы явно указываете, что ограничили размер record сверху и ваши 32K не смогут быть записаны в один record.

Вы явно указываете, что ограничили размер record сверху и ваши 32K не смогут быть записаны в один record.

"Госпидя ...", да вы рекорд от сектора не отличаете, и ещё меня на "профильные треды" отправляете. Там уже 3-й комментарий в котором ложное утверждение (ложное утверждение выделено жирным):

Sorry, that came out wrong. I meant to say: A large recordsize generally gives you better compression and less metadata overhead, but space is wasted on partly-filled records if compression is off

ashift диктует размер сектора zfs ПУЛА, recordsize диктует размер записи на конкретном dataset (по умолчанию 128к).
Размер сектора в идеале должен совпадать с блоком устройства, в противном случае или перерасход пространства или многократные перезаписи и падение производительности. Размер записи должен быть многократно больше размера сектора, что-бы в компрессии смысл был.

Посмотрите в исходники, modules/zfs/zio_compress.c и выше по иерархии.

ZFS пишет стрим!!!! Стрим размером с запись или меньше. Секторов займёт столько сколько нужно, а не по максимуму.

ARC от L2ARC вы тоже не отличаете, поэтому чушь несёте. Кстати ARC как и L2ARC содержат сжатые блоки если ФС сжата и блок сжимаемый.

Блок в ARC будет обновлён только, после того как физический блок будет записан, а он будет записан новый. И новый блок будет заюзан только новым запросом на чтение, т.к. COW. RWM цикл вам страшен только на hot блоках, или на искусственно созданной ситуации. Зачем вы вообще его сюда за уши притянули???

Не нужно мне здесь ссылки на "профильные треды" приводить. Чего там можно найти, того что нет в коде или документации ?????
Никакой сакральности во всём этом нет уже почти 15 лет. Есть даже разжёванная документация.

Вот вам древняя дока от оракла https://www.oracle.com/technetwork/server-storage/solaris10/config-solaris-zfs-wp-167894.pdf, там про размеры записи и db_block_size написано, чтоб админы не мучились. Это для OLTP нет выбора и размер записи, должен совпадать с размером блока БД, хотя для SSD это древнее правило уже можно просто похоронить.

Вот дока про с разделом компрессия https://openzfs.github.io/openzfs-docs/Performance and Tuning/Workload Tuning.html#compression

The uncompressed block size is set by the recordsize (defaults to 128KB) or volblocksize (defaults to 8KB) property (for filesystems vs volumes).

Вот доходчиво о компрессии для тех кто в код не умеет: https://klarasystems.com/articles/openzfs1-understanding-transparent-compression/

Детский сад.

Вот, замечательно, что вы включились. Плохо, что большая часть вашего текста по-прежнему нападки. Некоторые по прежнему без знания матчасти: ну, например, понятие сектор относится к устройству хранения, а не к zpool/zfs.


Пройдемся по конструктивной части.


ZFS пишет стрим!!! Стрим размером с запись или меньше.

Браво! А что случится, если вы ограничите этот ваш стрим в 4К и запишете 32К? Граничные случаи со стримом нулей и ему подобные давайте опустим, интересен случай с данными, подобными реальным.

Браво! А что случится, если вы ограничите этот ваш стрим в 4К и запишете 32К? Граничные случаи со стримом нулей и ему подобные давайте опустим, интересен случай с данными, подобными реальным.

Если Буратино очень хочет в топку, то туда ему и дорога. Не принуждает никто. Хочет - делает.

То есть, вы не имеете представления о том, что происходит в обсуждаемом случае.


А происходит там вот что:


Our hardware blocksize is 4KiB, and our desired maximum record size is 128KiB – so a typical record, uncompressed, will be stored in thirty-two 4KiB blocks. What if we’ve got “compression=lz4” set, and the LZ4 algorithm can achieve a raw 1.32 compression ratio, compressing that 128KiB of data down to 97KiB?
You need twenty-five total 4KiB blocks to store 97KiB of data – so while we’re still looking at a single 128KiB record, that record now occupies twenty-five blocks on disk, not thirty-two—an on-disk “compressratio” of 1.28.

Там же:


Higher recordsize Means Better Compression Ratios

Из этого следует простой вывод: запись сжимается целиком. И это, внезапно, логично: один и тот же код сможет обрабатывать записи сжатые и несжатые, просто в случае сжатой записи дополнительно вызывается декомпрессор — возвращающий типичную несжатую запись и не возвращающий внезапный терабайт нулей, с которым другие слои не знают, что делать.


О чем этот и говорит.

Ага, я и говорю ССЗБ. Давайте создадим проблему, и будем дружно всем рассказывать про неё. При этом и в документации и в статье вам говорят прямо, не делайте этого. А вы ну очень хотите этот случай внедрить в жизнь. Зато всем можно теперь рассказывать, что ZFS в компрессию не умеет :D

Дуракам закон не писан.
Если писан — то не читан.
Если читан — то не понят.
Если понят — то не так.


Спасибо за наглядную иллюстрацию.
Текст, в цитате, из вашего же источника взят ;)

Вы не представляете насколько это выглядит комично. Может у вас с английским плохо? Вы ведь этот "граничный случай", из пальца высасываете. Ну кто в здравом уме кроме тех кто сам себе враг, будет делать запись размером меньше или равным размеру сектора, при использовании компрессии? Ну нет ни одного практичного случая когда это нужно. И я вам с самого начала говорил, - больше размер записи (стрима), больше шансов, что данные займут меньше секторов. И чего вы так обрадовались, что вам закон не писан????
Даже для использования с оракл в OLTP профиле меньше 8к запись вы делать не станете (ну ведь не станете-же???? да???). А что это я вдруг за вас переживаю? Делайте как хотите.

Ну кто в здравом уме кроме тех кто сам себе враг, будет делать запись размером меньше или равным размеру сектора, при использовании компрессии?

Наверное, тот же, кто предложил установить ashift=12 и некий zfs блок в 4K, после чего каджит и создал к подветку, указав на неточность? Кто бы это мог быть, интересно? Наверное, Поттеринг, он всегда во всем виноват. Или Торвальдс. Ой, нет, это же сам thatsme!


Слушайте, вы уже неделю не в силах ни осмыслить ни свои комменты, ни то что вам пишут, ни прочитать свои же собственные пруфы, зато ударно выполняете танцы вокруг соломенного чучела, путаетесь в матчасти и агритесь. Первое время это еще можно было списать на жесткий абсистентный синдром, но праздники закончились и началась рабочая неделя. Пора прекращать бессмысленную возню ради возни и бампать пост руганью; если вам обсуждение еще актуально — напишите лучше в ЛС.

Наверное, тот же, кто предложил установить ashift=12 и некий zfs блок в 4K, после чего каджит и создал к подветку, указав на неточность? Кто бы это мог быть, интересно? Наверное, Поттеринг, он всегда во всем виноват. Или Торвальдс. Ой, нет, это же сам @thatsme!

У вас в голове каша. Я вам раньше об этом говорил, и доку привёл: ashift на размер записи не влияет, это размер сектора, который мапится в физ блоки драйва. Размер записи регулируется параметром recordsize. RTFM. Диалог пошёл по кругу...

Слушайте, вы уже неделю не в силах ни осмыслить ни свои комменты, ни то что вам пишут, ни прочитать свои же собственные пруфы, зато ударно выполняете танцы вокруг соломенного чучела, путаетесь в матчасти и агритесь. Первое время это еще можно было списать на жесткий абсистентный синдром, но праздники закончились и началась рабочая неделя. Пора прекращать бессмысленную возню ради возни и бампать пост руганью; если вам обсуждение еще актуально — напишите лучше в ЛС.

Как вы умудряетесь прикидываться специалистом, если даже доку, разжёванную и указанную в комментах выдержку осилить не в состоянии?

А кто вам говорит, что ashift влияет на размер записи-то? С кем вы спорите? Прочтите внимательнее сообщения вашего оппонента — он не говорил того, что вы ему приписываете.

Спасибо, но спор уже потерял всякий смысл. Человек внезапно обнаруживает секторы там где их уже не может быть, что приводит к терминологической путанице и оставляет гадать, что же он имел ввиду.


В принципе, понятно, что там, где подветка началась, он хотел сказать что-то другое.

Здоровья вам!

Ментального!

WAL получается по-сути последовательной однопоточной записью и не COW ФС его должны тоже быстро писать. А вот случайная запись должна быть очень быстрой. Правда последовательное чтение может оказаться непоследовательным по понятным причинам. Поэтому здесь правильно бенчмарк провести и посмотреть лучше COW ZFS под базу или хуже под различные нагрузки. Ну или может уже кто-то такие провел.

А вот со снапшотами на локальной ZFS я бенчмарк проводил на Proxmox и влияния снапшота не увидел на производительность.

>ZFS и так не быстрая, и лучшее ей применение это NAS & co, где данные редко модифицируются "по месту" (бэкапы и прочее), если её ставить на хостинг и там хорошая активность — это просто смерть производительности даже на NVMe, и это при выключенных компрессии и дедупликации, а с ними это вообще ужас-ужас — в начале всё ок но со временем за счёт фрагментации всё начинает тормозить просто ужасно, особенно если памяти на ARC не десятки гигабайт и процессор не очень многоядерный.

Тут в этом абзаце очень много вброса. Весь абзац состоит из внутренних противоречий. Я ограничусь следующим:

  1. Где и кто использует виртуализацию с "процессор не очень многоядерный". Вообще это не технический момент а финансовый. И если он вылез в плоскость "процессор не очень многоядерный", это ошибка дизайна и кап вложений в первую очередь.

  2. У меня в эксплуатации были массивы ZFS, под БД Oracle для DWH и CDR. Когда я их принял в эксплуатацию, то там уже была тупейшая ошибка дизайна, которая на самом деле упиралась в возможности Oracle 11g и ASM, - ограничение на размер LUN- 2ТБ. Т.е. JBOD поверх аналога RAID-10 ZFS. Объём занятого пространства на массиве более 220ТБ из доступных пользователю 270ТБ. И это сжатые БД, с коэффициентом компрессии у одной 3.5х у другой 11х. ZIL на выделенных SSD. Всё это хозяйство на 7ТБ и 14ТБ дисках, на запись более 24к 4k IOPS получить было невозможно. На чтение до 250к IOPS вполне тянуло. Самая большая проблема, это смешение DWH и CDR БД. Т.к. когда отчёты генерировать на DWH начинали, то всем было весело. Т.е. ещё одна ошибка дизайна. Однако, денег у компании на то что-бы разделить эти БД на разные СХД выбить было не реально. Всех радовало как много можно было впихнуть в ZFS, и все ныли, как это медленно. Вбухать кучу бабла не посчитав что и для чего будет использоваться и чего больше хочется, - сэкономить денег или побыстрей отчёты считать. Как обычно 7 шапок и вопрос лежит не в технической, а в финансовой области.

Также при тестах из ВМ есть риск, что чтение будет из ОЗУ хоста.

Здесь совет такой, что отдельно измерить скорость чтения и записи и сравнить. Если скорости отличаются в 10 раз и скорость чтения близка к скорости чтения ОЗУ, очевидно чтение из ОЗУ и происходит.

ZFS очень агрессивен в кэшировании (direct i/o игнорирует), так что если памяти у вас достаточно (32GB или больше) вы меряете производительность самой файловой системы, а не накопителя. Поставьте ограничение на ARC чтобы файл в него точно не влезал, и добавьте --fsync=1 к fio (убедившись что в ZFS не стоит sync=disabled) — тогда тест будет более реалистичным.

Нет в ZFS не выключен sync. Отдельного ZIL на SSD или отдельных дисках нет. ARC к записи не имеет отношения, а ZIL пишется всегда sync. В дополнение engine в fio sync, а у вас libaio. Я специально во всех тестах sync eingine использовал. fsync на каждом блоке будет i/o scheduler ZFS просто ломать оптимизацию ZIL.Надёжности записи не добавит, а производительность снизит.

С другой стороны на SSD тоже нужно с теми-же параметрами проверять с fsync и sync engine, и также печально будет себя вести deadline IO scheduler ядра.

С другой стороны RAID-10 на SATA SSD или SAS SSD дисках даст значительный прирост к производительности относительно NVME (от кол-ва дисков конечно зависит, но прелесть SAS в том, что он серийный). Т.е. на 24Gbit SAS вы имеете шанс все это 24Gbit выжать из набора дисков. А RAID на NVME не даст никаких плюсов, т.к. всё упрётся в UPI и то как линии UPI разведены.

также печально будет себя вести deadline IO scheduler ядра.

Поэтому для ssd нужно шедулер noop ставить и все будет хорошо. Для pcie дисков так вообще смерти подобно.

С другой стороны RAID-10 на SATA SSD или SAS SSD дисках даст значительный прирост к производительности относительно NVME (от кол-ва дисков конечно зависит, но прелесть SAS в том, что он серийный). Т.е. на 24Gbit SAS вы имеете шанс все это 24Gbit выжать из набора дисков. А RAID на NVME не даст никаких плюсов, т.к. всё упрётся в UPI и то как линии UPI разведены.

Оно в обоих случаях упрется в UPI линии для софтового рейда, а если SAS контроллер аппаратный, то еще в шину до него и в возможности самого контроллера, который в топовых вариантах выше 1млн IOPS не прыгнет. Я это уже проходил, когда собирал raid0 из sata ssd. Все упирается в контроллер, который еле вывозит десяток дисков. Скоро будем собирать на pcie дисках. Посмотрим на разницу.

Поэтому для ssd нужно шедулер noop ставить и все будет хорошо. Для pcie дисков так вообще смерти подобно.

Угу, не noop, а просто отключать I/O Scheduler? Ага, на синтетике в одно рыло на серваке классно выглядит, а при нагрузке от 10-ки ВМ будет невероятно весело... С другой стороны, если в сервере нет ничего кроме NVME, т.е. ни внешних накопителей по FC, ни внутренних, то может быть и с пачкой ВМ будет вполне норм. Но без тестов уверенности нет.

Тогда в любом случае, сравнивать без scheduler на SSD и ZFS пул, на котором fio с fsync работает, нельзя - это такая подгонка результата к желаемому значению. Т.е. лишь-бы "грамотно подать данные" или доказать правоту.

Edit:

По поводу SAS контроллера: ставьте 2 или более и на каждый свой пул. Но в отличии от NVME на М.2 просто упрётесь в кол-во х8 lanes PCI-E. Т.е. в любом случае выиграете, т.к. на каждом NUMA node будете как минимум один 16х PCI-E иметь. И лучше не RAID контроллер ставить а просто SAS expander, т.е. без RAID И кэшей. И ZFS вполне отлично вам тут поможет, на каждом NUMA node свой пул со своим контроллером. Дa CPU и ОЗУ будет жрать, - мама не горюй. Но скаллироваться будет всяко лучше чем RAID контроллер. И компрессия, это просто отличный способ снизить I/O.

Шедулер можно же для каждого девайса индивидуально выставить, если на серваке еще что-то есть. Не знаю как с ВМ, но для базы данных эффект очень серьезный. Шедулер просто нещадно выжирает весь CPU, а толку от него никакого даже на SATA SSD. Контроллер диска куда лучше справится с этой задачей, т.к. по определению больше знает.

И ZFS вполне отлично вам тут поможет, на каждом NUMA node свой пул со своим контроллером

Если ZFS не сможет (а она это не может, судя по всему) запинить свои треды к нужным ядрам и никогда не пересекать границы NUMA, то грош цена всему этому. Все равно трафик будет гулять по интерконнекту. Тоже самое с mdraid, который точно так же ничего это не умеет. Вот какой-нить ceph строить, вот там красота. Каждый OSD прибить к конкретному процессору и все.

Но в отличии от NVME на М.2 просто упрётесь в кол-во х8 lanes PCI-E

Не понял, вы о чем? Нормальный сторадж я буду строить на U.2 дисках с бэкплейном, к которому подключены все линии всех дисков без свитчей и прочей ерунды. Куда я упрусь в этом случае так это в пропускную способность памяти и интерконнект между процессорами. Никакие SAS экспандеры не вывезут такие скорости. Ставить на такое ZFS я уж точно не стану. Деньги на ветер, считай.

Шедулер можно же для каждого девайса индивидуально выставит

Не нужно. Он сам для NVME отключается, сейчас. с какой версии ядра это началось не скажу, но на 5.15 автовыбор без io scheduler для NVME по умолчанию.

Если ZFS не сможет (а она это не может, судя по всему) запинить свои треды к нужным ядрам и никогда не пересекать границы NUMA

Тут соглашусь. Даже если гипервизор контроллирует numa ноды, то ZFS на dom0 запинить на ноду не получится.

Не понял, вы о чем? Нормальный сторадж я буду строить на U.2 дисках с бэкплейном

А я имел в виду, что вы сможете взять SAS SSD и польза от ZFS таки будет, особенно учитывая сжатие и сокращение IO. И в любом случае 24/48Гбпс на SAS контроллер, это 6/12 накопителей. Т.е. в пропускную способность памяти и процессинговую способность ZFS конечно можно упереться гораздо раньше, чем на 12 накопителей данные уйдут. Но это дешевле и объём можно больше собрать.
В любом случае, получается, что для использования с ZFS и SAS SSD лучше всего использовать 1 процессорные модели серверов. Очень много места в пустую уйдёт.

Да и банально не нужно столько вычислительных мощностей, как по мне. ZFS конечно кушает, но не настолько, чтобы два проца совать туда. Особенно с нынешними моделями. Даже интел хорошие варианты имеет, не говоря уже об амд.

Да и в качестве примера можно посмотреть, что суют в энтерпрайз хранилки. Смех просто. А у многих внутри тот же самый ZFS и будет.

Я правильно понял, что у вас для виртуализации Hyper-V используется? Это только часть виртуалок крутиться в нем или весь хостинг на нем построен?

Если последнее, то можете рассказать по причинах/приемуществах его использования? В особеннности интересует окупаемость лицензий.

В особеннности интересует окупаемость лицензий.

А разве использование Hyper-V требует платных лицензий?

Всегда считал, что нет

Microsoft Hyper-V Server is a free product that delivers enterprise-class virtualization for your datacenter and hybrid cloud. Microsoft Hyper-V Server 2019 provides new and enhanced features that can help you deliver the scale and performance needs of your mission-critical workloads.

The Windows hypervisor technology in Microsoft Hyper-V Server 2019 is the same as what's in the Microsoft Hyper-V role on Windows Server 2019. It is a stand-alone product that contains only the Windows hypervisor, a Windows Server driver model, and virtualization components. It provides a simple and reliable virtualization solution to help you improve your server utilization and reduce costs.

Взято с: Try Hyper-V Server 2019 on Microsoft Evaluation Center

не подумать о numa это прям проблема новичка, в любом хостере админы очень быстро натыкаются на это неочень но узкое горлышко, я на первых строках статьи уже подумал об этом.. как то вы долго доходили

мы когда ceph тюнили до 100гигвсек быстро нащупали numa, задолго до того как достигли желаемых результатов

и второй момент: виндовый жиперви, сириусли?!?!?!?

Блин, даже энтепрайзные нвмешки время от времени вылетают. А поднимать данные с бэкапа, даже на нвме дикий даунтайм.

Если вы упёрлись в линии чипсета, почему нельзя воткнуть nvme через переходник PCI-E x16 слот? Тем паче, что в переходниках часто и аппаратный рейд может быть на борту.

вам было бы полезно почитать про современные линуксовые io-шедьюлеры. там подробно объясняется даже что важен сокет, в котором обратаывается прерывание.

Я недавно сделал небольшой тест производительности нескольких конфигураций software raid nvm и Sata SSD, на похожем железе

Стандартный mdadm
Стандартный mdadm
Сравнение с zfs
Сравнение с zfs

Правда, есть подозрение что на той версии zfs что у меня была флаг O_DIRECT типа продолжается, но не честно.

Второй график неправильный

На графиках ZFS local чтение наверняка из ОЗУ идет.

может быть, в той версии ZFS что у меня ( zfs-0.8.3-1ubuntu12.13 zfs-kmod-0.8.3-1ubuntu12.13 ) , поддержка флага O_DIRECT может быть кривая.

Её там вообще нет, он просто игнорируется. Поэтому всё ZFS на NVME медленновато из-за ARC (а с крутящимися дисками - наоборот, быстрее с ZFS).

В openzfs 3.0 обещают добавить полноценную поддержку O_DIRECT.

А можете уточнить объем дисков (чтобы их ТТХ посмотреть) и что за модель контроллера была.

Пока из того, что я вижу:
1) у ZFS на 4k медленная запись.
2) при подключении по NFS разницы между NVMe и SATA не очень видно (сопутствующие расходы на сеть и реализацию NFS дороже).
3) разница между 10G и 100G при работе по NFS не слишком заметна.

железо:

1: Supermicro SYS-2029U-TN24R4T : Supermicro X11DPU ; Xeon Silver 4108 CPU x2; SSD INTEL SSDPE2KX080T8 x 6

2: Nvidia DGX-1: Xeon E5-2698 v4 x2 ; LSI MegaRAID SAS-3 3108 ; SSD SATA Samsung PM863 x4

При NFS - так и есть. Скорость удаётся поднять только если использовать RDMA, но в моём случае работало нестабильно ( периодически вешало систему).

Не встречал подобного опыта что обнаружил я - как ведут себя различные фс на программном рейде 1, 10, 5, 6 из nvme дисков (про аппаратный даже и говорить не стоит, там никакая производительность), так вот - на ext4 производительность в любом рейде только падала по сравнению даже с 1 диском, в то же время на xfs почти что кратно количеству дисков в массиве возрастала. Тестил на серверах amd epyc rome 2 с кучами u.2 nvme дисков.

У меня рейд на nvme прекарасно работает.

# hdparm -Tt /dev/nvme1n1p1


/dev/nvme1n1p1:

Timing cached reads:   38430 MB in  1.98 seconds = 19362.30 MB/sec

Timing buffered disk reads: 190 MB in  0.29 seconds = 658.44 MB/sec


# hdparm -Tt /dev/mapper/cmvg00-tmp


/dev/mapper/cmvg00-tmp:

Timing cached reads:   37902 MB in  1.98 seconds = 19094.24 MB/sec

Timing buffered disk reads: 1746 MB in  3.00 seconds = 581.95 MB/sec

Первый тест для простого раздела на nvme, как видно, а второй для виртуальной партиции на raid + encript + lvm.


честно говоря, не понял, что хорошего в ≈600 МБ/с

Какие хорошие данные! Спасибо. Вы же понимаете, что основная потеря идёт на encript… Но без него - никак. А так, реально, чуть больше 11% потерь, это ни о чём.

Ваша главная и наверно единственная ошибка эт сборка и тестирование на интеле.

Ну кто в здравом уме в 2021 году (да и примерно с 2018) собирает новые серверы на интел? Тока от нищеты, отсутсвия денег или так себе домой можно.

Соответственно поимели геморой закономерный.

Только АМД. Только Epyc. ТОЛЬКО Милан.

Уже суть всем стало ясно с выходом 12 поколения что Интел это мусор.

Есть надежда на Сапфир-рапид но то что показали в виде Милан-Х или новых ТР про как минимум будет не хуже.

Sign up to leave a comment.