Table of Contents

Тюнинг XigmaNAS на слабом железе

Тонкие настройки производительности на старом железе.

Профиль машины: 2 ядра CPU ~1.3 ГГц, 4 ГБ RAM, 4 механических диска в пуле ZFS raidz1, загрузка с USB-флешки.

ZFS: ARC

# loader.conf
vfs.zfs.arc_max=1G

ARC по умолчанию растёт до ~половины RAM — на 4 ГБ это неприемлемо, конкурирует за память с остальными сервисами. Дальнейшее занижение ниже 1G не имеет смысла — теряется эффективность кэша без ощутимого выигрыша в свободной памяти.

ZFS: primarycache по датасетам

Датасет primarycache Причина
pool root metadata директории/ACL, выигрывает вся файловая иерархия, включая SMB
датасет с активно перечитываемыми данными all (local override) реальный выигрыш от кэша данных
датасет с данными “пишем раз — не перечитываем” (архив бэкапов, транзитное шифрованное хранилище) metadata не вытеснять из маленького ARC то, что реально нужно
zfs set primarycache=metadata tank
zfs set primarycache=all tank/active_data

ZFS: датасет под backup-репозиторий

Параметр Значение Причина
compression off бэкап уже сжат средствами клиента резервного копирования
recordsize 1M крупные последовательные файлы — меньше метаданных/чек-сумм на объём
logbias throughput приоритет пропускной способности при больших последовательных записях
primarycache metadata данные пишутся раз, почти не перечитываются

ZFS: датасет с зашифрованным транзитным содержимым

`compression=off` — если через датасет проходят уже зашифрованные блоки (см. статью про Syncthing, тип папки receive-encrypted): зашифрованные данные несжимаемы, попытка сжатия — чистые потери CPU.

ZFS: общие дешёвые тюнинги

zfs set xattr=sa redundant_metadata=most tank

Своп

Не на USB-флешку (загрузочный носитель): медленно под нагрузкой, ограниченный ресурс перезаписи флеш-памяти (свопинг ускоряет деградацию носителя, который одновременно и загрузочный).

Не на zvol ZFS-пула: запись в своп идёт через ZFS-стек, которому самому нужна память на I/O (ARC, транзакционные группы) — риск дедлока под давлением памяти.

Правильный вариант — raw-разделы (не zvol), собранные в RAID0 через `gstripe`, мимо ZFS-стека целиком:

Механизма создания разделов в GUI нет, поэтому нужно работать через CLI:

gpart add -t freebsd-swap -a 1m -s 2g -l swap0 ada0
gpart add -t freebsd-swap -a 1m -s 2g -l swap1 ada1
gpart add -t freebsd-swap -a 1m -s 2g -l swap2 ada2
gpart add -t freebsd-swap -a 1m -s 2g -l swap3 ada3
gstripe label -v swap0 /dev/ada0p2 /dev/ada1p2 /dev/ada2p2 /dev/ada3p2

Регистрация в XigmaNAS: System → Advanced → Swap, Type = Device, Device = `/dev/stripe/swap0`.

Ограничение ZFS raidz: ужать раздел под живым raidz-vdev нельзя (расширение поддерживается — RAIDZ expansion, обратная операция нет). Разметку под своп на тех же дисках, что и raidz-пул, закладывать заранее при создании пула — иначе единственный путь получить место под неё, это пересоздать пул.

Объём: ориентир “2× RAM” для legacy-железа; если нужен kernel core dump — своп не меньше объёма RAM.

ZFS: latency vs throughput

На слабом CPU/дисках приоритет — короче худший случай задержки отклика, а не пиковая пропускная способность. Актуально при потоке мелких операций записи (много мелких файлов разом).

Параметр Дефолт Значение Требует ребута Причина
vfs.zfs.txg.timeout Нет (live sysctl) Короче окно накопления транзакционной группы — короче потенциальный стопор на её фиксации
vfs.zfs.dirty_data_max_percent 10% от RAM 5% Да — read-only tunable, только через loader.conf Меньше данных копится в памяти перед принудительным сбросом на диск
vfs.zfs.vdev.async_write_max_active 10 3 Нет (live sysctl) Глубина очереди записи на vdev — на старых дисках без развитого NCQ большая очередь удлиняет отклик для операций, ожидающих за длинной очередью
vfs.zfs.vdev.sync_write_max_active 10 3 Нет (live sysctl) То же для синхронных записей
# loader.conf / sysctl.conf
vfs.zfs.txg.timeout=1
vfs.zfs.dirty_data_max_percent=5
vfs.zfs.vdev.async_write_max_active=3
vfs.zfs.vdev.sync_write_max_active=3

arc_min — не трогать. Может казаться логичным зафиксировать минимальный размер ARC, чтобы не проседал под нагрузкой, но на машине с и так туго рассчитанной памятью это забирает у ARC возможность сжаться и отдать память другим процессам именно тогда, когда она нужнее всего (при пиковой нагрузке). Оставлять `arc_min` неактивным — ARC пусть сам решает, когда сжаться.

vnode-лимит при большом числе мелких файлов

`kern.maxvnodes` — верхняя граница живых vnode в системе. Если по дереву датасета проходит live filesystem watcher (см. статью про тюнинг Syncthing — секция про fsWatcher/kqueue) или просто идёт операция над деревом с сотнями тысяч мелких файлов/директорий, число vnode может подступить к лимиту — система начинает агрессивно вытеснять vnode, что способно сериализовать файловые операции по всей системе, а не только у процесса-триггера.

Диагностика: `sysctl kern.maxvnodes vfs.numvnodes` — если `numvnodes` устойчиво держится близко к `maxvnodes` во время нагрузки, лимит тесен. Поднять его — не панацея (каждый vnode — расход памяти ядра), но если основная причина нагрузки на дерево устранена на уровне приложения (например, отключением live-watcher), поднимать лимит обычно не требуется.

Проверка: конфиг ≠ реальность

Значение в GUI/loader.conf/sysctl.conf не гарантированно применяется на живой системе. Встречается:

Проверка: `sysctl <параметр>` на живой системе после любой правки loader.conf/sysctl.conf — не доверять только факту наличия строки в конфиге.

Расписание акустики дисков

AAM (Automatic Acoustic Management), уровень 1–127: 1 — минимальный шум, 127 — максимальная производительность/шум.

ataidle /dev/ada0          # проверка поддержки и текущего значения
ataidle -A 1 /dev/ada0     # тихий режим
ataidle -A 127 /dev/ada0   # полная производительность

Расписания в GUI нет — через cron:

0 23 * * * root for d in ada0 ada1 ada2 ada3; do /usr/local/sbin/ataidle -A 1 /dev/$d; done
0 6  * * * root for d in ada0 ada1 ada2 ada3; do /usr/local/sbin/ataidle -A 127 /dev/$d; done

Cron: подводные камни

Параметры, оставленные без изменений

Параметр Значение Причина не менять
APM диска максимальная производительность сервер с бэкапами, экономия питания не приоритет
HDD standby timer задаётся в минутах, не в секундах при частом фоновом обращении к дискам (мониторинг раз в несколько минут) порог простоя физически не достигается
Power Mode CPU adaptive не проседает на всплесках нагрузки (в отличие от minimum), не расходует лишнее (в отличие от maximum)