LINUX.ORG.RU
ФорумAdmin

Тестирование производительности ZFS на SSD /2023

 , ,


6

6

Скоро (ближе к концу января) буду вводить в эксплуатацию сервер, хочу потестить производительность ZFS.

Цели:

  • выявить и исправить косяки в конфигурации
  • определить готовность ZFS к разного вида нагрузкам
  • лучше понять, как тестировать дисковую подсистему
  • лучше понять, как настраивать ZFS

Тестировать буду Intel P5800X (Optane) и Samsung PM1735 (TLC). Будет средний сервер на Xeon’e. Дистрибутив — Proxmox VE.

Принимаются пожелания (в виде указаний по настройке ZFS и конфигов/команд fio).

Предыдущее тестирование (2019 г.)

Тема в reddit/zfs. Может там чего-нибудь дельного посоветуют.

★★★★★

Последнее исправление: Harliff (всего исправлений: 3)

О, я с подобным кейсом сталкивался.

Вероятно очевидные вещи скажу.

Пул и тома

  1. Включить autotrim.

  2. Физические диски могут быть с конфигурируемым размером блока, в том числе и меньшим, чем физический. В таком случае тоже нужно выбрать тот, который соответствует физическому.

  3. Очень важно, что бы trim работал и не было ущерба производительности, правильно выставить ashift, в соответствии с размером физического блока диска. После того как пул создан, поменять это значение невозможно.

  4. Тома (zvol) следует создавать с размером блока, кратным ashift и физическому блоку.

  5. Среди драйверов витуальных дисков только один умел в trim, его и нужно использовать. Который - не помню. Если этого не сделать, освобождённые блоки внутри виртуалки не будут освобождены на пуле хоста. Т.е. фактически это сломает thin provisioning. Никакого профита от thick provisioning в плане производительности нет, т.к. пулы ZFS используют CoW всегда.

  6. То же касается и размера блока FS внутри виртуалок. Он можен быть каким угодно, но обязан быть кратен размеру блока виртуального тома (zvol).

Т.е. здесь в целом всё должно быть идеально выравнено. Иначе не будет освобождаться место или будет страдать производительность.

Датасеты ZFS

  1. Хэши. Дефолтный хэш вроде fetcher4, это не всегда оптимально. sha256/sha512 могут оказаться быстрее, если процессор имеет нужные наборы инструкций. skein может оказаться быстрее, если таковых наборов инструкций нет. Поменять позже - можно, но поменяется он только для новых записей, старые пересчитываться не будут. Принудить ZFS пересчитать хэши можно только полным копированием датасета, либо перезаписью каждого блока.

  2. Сжатие. Выбирается под задачу, но в общем случае стоит попробовать lz4, может оказаться что с ним пропускная способность вырастет. Плюс если данные хоть сколько-нибудь жмутся, это поможет снизить износ дисков. Аналогично с хэшем, разжимать и сжимать без копирования датасета или перезаписи всех блоков ZFS не будет.

  3. Для FS стоит включать dnode=auto и xattr=sa. В мане написано зачем. Если коротко - даёт буст производительности на системах, с самбой или SELinux, которые активно используют эти xattrs.

  4. recordsize. Дефолт - 128KiB. Значение должно быть кратным физическому блоку. Менять рекомендуется только если содержимое датасета само делится на блоки. Например, если это БД. Здесь важно понимать 2 вещи: фактическая запись на диск может быть меньше, но любая запись кратна физическому блоку. Скажем, при физическом блоке в 8KiB ты пишеш файл размером 80KiB, который после сжатия станет занимать 57KiB. Будет одна запись размером в 64KiB.

    • Если БД пишет блоками по 4KiB, но делает это в один длинный файл, будут происходить перезаписи по 128KiB, что снижает производительность. Здась оптимальнее сделать recordsize=4KiB.

    • Если на ФС хранятся какие-то тяжёлые видосы, которые можно загружать последовательно, то загружаться будут блоки по 128KiB, что тоже не очень оптимально. Лучше в таком случае сделать recordsize=1MiB.

    • В любом случае, ZFS пишет/читает/шифрует/сжимает эти записи раздельно и целиком. Т.е. если данные хорошо жмутся, но блок маленький, сжатие будет страдать. Записи целиком загружаются в ARC и выгружаются тоже только целиком.

ARC

  1. Работает - не трогай. Просто дай ему оперативку, а дальше он сам. Посмотреть насколько он хорошо справляется можно в arc_summary. Мне ничего не пришлось делать что бы получить 90% hit ratio и нормальный префетч.

  2. L2ARC. Если удастся где-то взять NVMe ощутимо быстрее чем те, что ты перечислил - можешь подрубить, производительность вырастет. Но кмк это в основном имеет смысл на гибридных системах HDD + SSD/NVMe, где разница в производительности ощутимая.

  3. ZIL. Аналогично с L2ARC, но для записи, при том синхронной.

anonymous-angler ★☆
()

Продолжу свой монолог. Файловая система или том с CoW (Например ZFS) всегда будет проигрывать в производительности решению без такового (Например md + ext4). Для этого нужно просто понять как оно работает.

Без CoW

  1. Пишем блок данных поверх.
  2. Пишем блок метаданных поверх.

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

С CoW

  1. Пишем блок данных. Поверх - нельзя, CoW же. Пишем в другое место. Теперь обновлённый кусок файла есть, но указатели в родительском узле дерева на него не указывают.
  2. Перезаписывать родительский узел дерева тоже нельзя. Пишем в другое место. Но теперь указатели в родительском узле родительского узла не указывают на нужный блок.
  3. Эта рекурсия будет повторяться до самого верха, где корневой узел просто имеет несколько копий в фиксированных местах диска.

Думаю очевидно что деревья могут быть глубокими и таких записей будет много. У ZFS есть планировщик, который позволяет группировать такие перезаписи, но даже с ним алгоритмическая сложность ощутимо выше. Ну и такое копирование приводит к ужасному фрагментированию, и с этим ничего нельзя сделать.

Плюсов такого подхода как минимум 2:

  1. Моментальные снапшоты (Нужно просто где-то сохранить указатель на текущий корень датасета.
  2. Атомарность. Транзакция либо завершится целиком, либо целиком будет потеряна. Что соответствует фокусу на целостности данных.

Т.е. отвечая на вопрос из прошлого треда: нет, приблизить производительность ZFS к LVM (если там нет CoW) - невозможно.

anonymous-angler ★☆
()
Последнее исправление: anonymous-angler (всего исправлений: 2)
Ответ на: комментарий от anonymous-angler

Включить autotrim.

Спорно. Как по мне, лучше иметь предсказуемую производительность диска. По сему, ИМХО, лучше по крону выполнять zpool trim zroot раз в сутки.

правильно выставить ashift, в соответствии с размером физического блока диска

Так он вродь давным давно автоматом выставляется в оптимальное значение при создании пула.

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

Самый быстрый вариант - zfs send | zfs recv

skein может оказаться быстрее, если таковых наборов инструкций нет.

В доке сказано, что skein на 80% быстрее sha-256 на 64-bit железе (независимо от наличия инструкций).

Для некоторых датасетов с временными данными можно вовсе отключить контрольные суммы + sync=disabled

Сжатие.

По моим личным тестам zstd показал лучший коэффициент сжатия нежели lz4 при сравнимой скорости сжатия/распаковки. Как минимум, стоит на него взглянуть. Возможно при определенном ворклоде zstd будет более оптимальным выбором.

Еще добавлю:

  • отключить atime, так как в большинстве случаев он не нужен.
  • если датасет только для данных, для безопасности можно exec, setuid, sharenfs, acltype выставить в off. Возможно это даже ускорит его немного.
iron ★★★★★
()
Ответ на: комментарий от anonymous-angler

Работает - не трогай. Просто дай ему оперативку, а дальше он сам.

Это зависит от ворклода сервера. Если это файлопомойка - то можно ARC не ограничивать. Если же есть БД/веб-сервер то лучше ограничить, чтоб не было «драки» за оперативку. В большинстве гайдов рекомендуют ограничивать в силу специфики работы ARC с памятью.

iron ★★★★★
()
Ответ на: комментарий от iron

zstd показал лучший коэффициент сжатия нежели lz4

Естественно, у него же есть энтропийное кодирование в отличие от.

при сравнимой скорости сжатия/распаковки

А вот это врядли. Если на сжатии ещё возможны варианты, то при распаковке lz4 может и memcpy обойти )

Возможно при определенном ворклоде zstd будет более оптимальным выбором.

Ну чем больше размер блока и чем лучше сжимаются данные, тем он будет выгоднее. Преимущественно чтение, сайты, тексты, исходники, базы... Но там и lz4 достаточно хорош.

GAMer ★★★★★
()
Ответ на: комментарий от iron

Спорно. Как по мне, лучше иметь предсказуемую производительность диска. По сему, ИМХО, лучше по крону выполнять zpool trim zroot раз в сутки.

Согласен. Ситуативно. Но ZFS, судя по ману, сама достаточно умная что бы тримить не сразу.

Так он вродь давным давно автоматом выставляется в оптимальное значение при создании пула.

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

Самый быстрый вариант - zfs send | zfs recv

Это я и подразумевал под полным комированием датасета.

В доке сказано, что skein на 80% быстрее sha-256 на 64-bit железе (независимо от наличия инструкций).

В man zfsprops я такого не вижу.

Для некоторых датасетов с временными данными можно вовсе отключить контрольные суммы + sync=disabled

Если цель - производительность - возможно. Если цель - целостность данных, то не стоит так делать. Потому что даже временные данные, будучи повреждёнными и успешно считанными, могут создать проблемы.

По моим личным тестам zstd показал лучший коэффициент сжатия нежели lz4 при сравнимой скорости сжатия/распаковки. Как минимум, стоит на него взглянуть. Возможно при определенном ворклоде zstd будет более оптимальным выбором.

У lz4 ощутимо выше скорость распаковки. В целом я его расцениваю как «хоть какое-то сжатие почти без ущерба производительности». Ну и насколько мне известно, он дешевле в плане оперативки и цп. Но тут тоже всё субъективно и под задачу.

отключить atime, так как в большинстве случаев он не нужен.

Кмк лучше включить relatime, тогда обновление atime будет происходить параллельно с обновлением mtime/ctime, что условно бесплатно, т.к. они все наверняка в одном блоке. Плюс данного подхода в том, что atime будет обновляться хотья бы иногда.

anonymous-angler ★☆
()
Ответ на: комментарий от iron

Согласент, тоже ситуативно. Однако у такого подхода тоже есть серьёзный минус: если память не занята, а ARC ограничен, то будет некоторый ущерб производительности ради ничего. Если бы я столкнулся с подобной необходимостью, то попробовал бы поискать альтернативные решения, не подразумевающие жёсткого оганичения размера ARC. Вероятно можно задать минимум и задержку, после которой он начнёт присваивать незанятую «лишнюю» память.

anonymous-angler ★☆
()
Ответ на: комментарий от GAMer

А вот это врядли. Если на сжатии ещё возможны варианты, то при распаковке lz4 может и memcpy обойти )

Ну это уже кажется преувеличением. Не могу себе представить как.

anonymous-angler ★☆
()
Ответ на: комментарий от anonymous-angler

В man zfsprops я такого не вижу.

# man 7 zpool-features

     skein
             GUID                  org.illumos:skein
             DEPENDENCIES          extensible_dataset
             READ-ONLY COMPATIBLE  no

             This feature enables the use of the Skein hash algorithm for
             checksum and dedup.  Skein is a high-performance secure hash
             algorithm that was a finalist in the NIST SHA-3 competition.  It
             provides a very high security margin and high performance on
             64-bit hardware (80% faster than SHA-256).  This implementation
             also utilizes the new salted checksumming functionality in ZFS,
             which means that the checksum is pre-seeded with a secret 256-bit
             random key (stored on the pool) before being fed the data block
             to be checksummed.  Thus the produced checksums are unique to a
             given  pool, preventing hash collision attacks on systems with
             dedup.

iron ★★★★★
()
Последнее исправление: iron (всего исправлений: 1)

О, супер тема, подпишусь. Сам год назад тестировал так:

fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=test --filename=test --bs=4k --iodepth=64 --size=4G --readwrite=randrw --rwmixread=75

И с direct=0 тоже.

Но никак не тюнил, не оптимизировал. И всё было очень плохо

overmind88 ★★★★★
()
Ответ на: комментарий от anonymous-angler

Не могу себе представить как.

Я тоже не мог )
Суть такова...
memcpy таки приходится сначала читать память, потом её писать. Если брать достаточно большой объём данных, читать придётся из физической планки памяти.
А у lz4, если данные хорошо пожаты, чтение сможет идти хоть из L1 кэша, что конечно куда быстрее шины памяти.

GAMer ★★★★★
()
Ответ на: комментарий от anonymous-angler

Т.е. отвечая на вопрос из прошлого треда: нет, приблизить производительность ZFS к LVM (если там нет CoW) - невозможно.

В целом — «да, конечно», но бывают кейсы, где ZFS уделывает LVM на специфических нагрузках. Как ни странно…

Выдержки для Ъ:

наш основной биз - виртуальные пространства для энтерпрайзов на базе Parallels RAS… По сути мы виртуализированное облако с кучей виртуалок, в основном под виндой, на которой работают офисные сотрудники.

… мы никаких проблем не наблюдаем и наоборот очень четко видим положительные влияния ZFS ARC и большого количества RAM в паре.

… мы бенчмаркили ZFS vs LVM (это было с выходом 0.8) и на конечных тестах с продуктами MS Office (они для нас принципиальны и у нас есть свой бенчмарк для ворда, экселя и аксеса) - сетап с ZFS уделал LVM-ный аналогичный почти на 60% в производительности для нас важной.

Harliff ★★★★★
() автор топика
Последнее исправление: Harliff (всего исправлений: 2)
Ответ на: комментарий от anonymous-angler

4.Тома (zvol) следует создавать с размером блока, кратным ashift и физическому блоку.

Зачем этот пункт?

ZVOL и так принадлежит пулу (который создался с учётом размера физического сектора диска/страницы флэша и ashift - его поменять невозможно).

iZEN ★★★★★
()
Ответ на: комментарий от Harliff

Здесь упоминается ARC. С ним может и да, но в прошлых тестах ты вроде бы его отключал насколько возможно. Я же говорю про сферическое в вакууме решение с CoW vs no-CoW, без ARC и прочего.

anonymous-angler ★☆
()
Последнее исправление: anonymous-angler (всего исправлений: 1)