Проект

Общее

Профиль

Тюнинг zfs

SYSCTL

  • vm.kmem_size, vm.kmem_size_max – количество памяти выделяемое под использование ядром. Не рекомендуется указывать больше, чем установлено оперативной памяти.

  • vfs.zfs.prefetch_disable=1 – отключение режима prefetch. Режим, когда система "предсказывает" какие данные будут прочитаны и заранее читает их, соответственно значительно ускоряет работу файловой системы. На amd64 при памяти менее 4ГБ он отключается автоматически. (У меня используется архитектура i386, а на ней рекомендуется отключить данный режим.)

  • vfs.zfs.arc_max - количество памяти выделяемое для хранения кэшированных данных пула файловой системы. Точнее (из первоисточника): ARC - ZFS adaptive replacement cache. Там же написано, что по умолчанию ARC пытается получить всю оперативную память, кроме 1ГБ. Но, при приоритетных запросах на выделение памяти приложением/процессом, немедленно высвобождает требуемое количество. Кстати, Oracle, в официальных манах не рекомендует устанавливать чрезмерный размер ARC, дабы уменьшить конкуренцию за выделение памяти в системе между ZFS и приложениями!

Для выделения памяти под использование ядром более 512МБ необходимо пересобрать ядро с options KVA_PAGES=512, или с большим значением (читать /sys/i386/conf/NOTES). По умолчанию, ядру FreeBSD доступно 1ГБ из 4ГБ возможных на архитектуре i386. Для выделения большего количества памяти необходимо соответственно увеличить значение KVA_PAGES. Стоит обратить внимание на то, что увеличение vm.kmem_size может привести к неработоспособности некоторых программ, которые используют фиксированную область оперативной памяти.

В случае, если были установлены неподходящие параметры в loader.conf и система не загружается (например, из-за паники ядра при слишком больших установленных значений vm.kmem_size и vm.kmem_size_max), необходимо выбрать вариант загрузки через командную строку и установить проверенные параметры, после чего загрузить ядро (например):

OK set vm.kmem_size=1000M
OK set vm.kmem_size_max=1000M
OK boot /kernel

После загрузки не забыть изменить эти параметры в loader.conf...

Вообще из экспериментов стало понятно, что сколько не выделяй ZFS памяти под кэш - все переваривает :) Задача состоит как раз в том, чтобы найти оптимальный объем, обеспечивающий максимальную производительность и при этом обеспечить некоторую избыточность...

В помощь можно воспользоваться скриптом, который отображает использование памяти файловой системой ZFS:

#!/bin/sh -

TEXT=`kldstat | awk 'BEGIN {print "16i 0";} NR>1 {print toupper($4) "+"} END {print "p"}' | dc`
DATA=`vmstat -m | sed -Ee '1s/.*/0/;s/.* ([0-9]+)K.*/\1+/;$s/$/1024*p/' | dc`
TOTAL=$((DATA + TEXT))

echo TEXT=$TEXT, `echo $TEXT | awk '{print $1/1048576 " MB"}'`
echo DATA=$DATA, `echo $DATA | awk '{print $1/1048576 " MB"}'`
echo TOTAL=$TOTAL, `echo $TOTAL | awk '{print $1/1048576 " MB"}'`

Также, нужно учитывать, что чрезмерно большое значение vm.kmem_size может привести к панике ядра при загрузке! Исправить ситуацию можно в приглашении загрузчика командой set vm.kmem_size="512M" или с другим проверенным значением.

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

Что еще?
kern.maxvnodes (/etc/sysctl.conf) - такие элементы файловой системы, как файлы и каталоги представлены в ядре при помощи "виртуальных узлов" (vnode). Увеличение числа узлов может уменьшить нагрузку на дисковую подсистему. На этот фактор стоит обратить внимание лишь в тех случаях, если система близка к исчерпанию таблицы vnode, только тогда значение этой переменной нужно увеличивать.

Количество использованных vnode системой (текущее значение) можно отобразить командой:

sysctl vfs.numvnodes

Максимальное установленное кол-во vnode в системе:

sysctl kern.maxvnodes

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

ZIL - ZFS Intent Log (лог намерений ZFS)

Используется во время операций синхронной записи. ZIL является неотъемлемой частью файловой системы и не рекомендуется его отключать. При отключенном режиме достигается значительный прирост производительности, однако это может привести к нарушению целостности данных ( !!! ), поскольку ZFS будет игнорировать требования синхронизации транзакций таких приложений, как Базы Данных и NFS.

Проверить значение параметра sync для датасета:

zfs get sync tank/dataset

Возможные значения:

sync=standard - значение по умолчанию. Во время синхронных операций ZFS производится запись в Intent Log
sync=always - каждая транзакция файловой системы записывается ZIL. Очевидно, что данный режим приведет к значительному падению производительности.
sync=disabled - отключить ZIL

Начиная с ZFS v.28 можно выборочно изменять режим ZIL для каждого датасета zfs-пула:

zfs set sync=disabled tank/dataset

Несмотря на вышеописанное, нашел на некоторых форумах рекомендации по отключению ZIL на датасетах, которые работают с NFS... В общем, решайте сами что для Вас важнее: скорость или надежность ;)

Время доступа

На FreeBSD, каждый раз, когда происходит обращение к файлу время доступа (atime) обновляется. Это может сформировать большое количество записей на диск на сервере работающем с большим числом файлов. В таком случае вы захотите отключить atime (время доступа) для пострадавших данных или для всего пула. Отключение atime может улучшить производительность всех типов приложений серверов.

zfs set atime=off dataset

Сжатие данных

Использование сжатия данных в ZFS сохраняет пространство но имеет негативный эффект на производительность CPU системы и отзывчивости. С другой стороны, включение сжатия (главным образом LZJB) может повысить производительность ваших данных, особенно на медленных носителях. В частности стоимость сжатия gzip существенно больше процессорного времени, чем меньший уровень сжатия LZJB сжатие. Поэтому я рекомендую использовать сжатие данных только если вы имеете сжимающиеся данные и наборы данных это не бутылочное горлышко производительности или если у вас мало дискового пространства. Наборы данных с низкой активностью содержат, например, журнальные файлы хорошие кандидаты для gzip сжатия. Если вы имеете быстрый накопитель с достаточным пространством и нужна первоклассаная производительность, отключите сжатие набора данных для поврежденных наборов данных.

zfs set compression=[on|off] dataset

Серверы баз данных

Для баз данных таких как PostgreSQL и MySQL, пользователям рекомендуется хранить их в наборе данных, созданных различными размерами записи, чем задано по умолчанию 128 килобайт.
Для PostgreSQL и MySQL (MyISAM хранилище), устанавливается размер записи в 8 килобайт перед популярным набором данных:

zfs create -o recordsize=8k tank/mysql

Для MySQL InnoDB хранилище файлов (не журналируемые) устанавливают размер записи в 16 килобайт, журналы должны быть оставлены с размером записи по умолчанию (вам нужно распространить данные в несколько наборов данных, которые имеют различные размеры записи).

NFS серверы

Если обмен наборами данных ZFS на сервере NFS с большим количеством записей, ZIL может быть вашим бутылочным горлышком. Для улучшений производительности, вы можете захотеть переместить ZIL на отдельное устройство журнала (быстрый SSD диск) или попробовать отключить ZIL для поврежденных данных. Отключение ZIL может привести к повреждению NFS клиента.

zfs set sync=disabled dataset

ZFS и 4к Сектор Диска

Первоначально жесткие диски используются для хранения данных в 512 байтах физических секторов. Большие жесткие диски сегодня используют Расширенный Формат (4к секторов) и обеспечивают 512 байт сектора в режиме совместимости. В FreeBSD, указанные диски обычно все еще сообщают о размере сектора в 512 байт.

ada0: 2861588MB (5860533168 512 byte sectors: 16H 63S/T 16383C)

ZFS использует это значение, когда определяет размер блока для устройства, когда добавляет его в пул (или когда пул создан). Просмотрите вашу конфигурацию устройства пула, используя следующую команду:

zdb –C [poolname]

Параметр asiff описывает размер блока ZFS используемый размер как 2[ashift]. Значение "9" означает 512 байтный сектор. Чтобы иметь 4 килобайтные блоки, необходимо значение "12".

Пользователи сообщают о плохой производительности с Расширенным Форматом жестких дисков и ashift=9, особенно в конфигурациях RAIDZ. Чтобы создать пул оптимизированный для 4 Кбайт секторам, мы должны сделать размер блока ZFS соответствующим размеру физического сектора, некоторые делают трюк с поддельным устройством gnop. Давайте предположим, что мы хотим создать новый пул на устройстве /dev/ada0.

gnop create –S 4096 ada0
zpool create tank ada0.nop
zpool export tank
gnop destroy ada0.nop
zpool import tank
zdb –C tank | grep ashift

На настройке с 4к блоком, небольшие файлы до 4к всегда занимают один целый блок. Метаданных ZFS во много раз меньше чем 4кб. Пожалуйста, обратите внимание, что использование ashift=12 увеличивает начальное пространство необходимое для метаданных до довольно большого количества (около 5% от общего размера диска). В зависимости от ваших данных, может увиличиться нагрузка на ваш пул при заполнении данными (например, много мелких файлов). Так что это эффективный компромисс между производительность и свободным дисковым пространством и вам придется решать, что для вас важней.