Механизмы кэширования ARC и L2ARC в ZFS

У ZFS есть две интересные функции, которые значительно повышают производительность операций чтения. Речь идет о механизмах кэширования ARC и L2ARC. В этой статье рассмотрим их подробнее.

Статья является переводом и адаптацией англоязычной статьи из материалов проекта ZFS Build.


ARC

ARC, или кэш адаптивной замены, является очень быстрым кэшем, расположенным в оперативной памяти сервера (ОЗУ). Объем доступного на сервере ARC по умолчанию составляет всю оперативную память, минус 1 Гбайт.

Например, на ZFS-сервере с 12 Гбайт ОЗУ для ARC будет выделено до 11 Гбайт, что означает, что ZFS-сервер сможет кэшировать 11 Гбайт наиболее часто используемых данных. Любые запросы на чтение данных в кэше могут обслуживаться непосредственно из кэша ARC, а не с более медленных жестких дисков. Это обеспечивает заметное повышение производительности для данных, к которым обращаются чаще всего.

L2ARC

Чтобы поддерживать ARC большим, требуется установить на сервер как можно больше оперативной памяти. В какой-то момент добавление большего объема памяти становится неразумно дорого или невозможно. Тогда можно начать использовать L2ARC. L2ARC — это кэш адаптивной замены второго уровня. Данный кэш располагается на высокопроизводительных дисковых устройствах, чаще всего на SATA или NVMe накопителях типа SSD. Когда диски кэша присутствуют в пуле дисков ZFS, они кэшируют часто используемые данные, которые не помещаются в ARC.

SSD-диски медленнее системной памяти, но все же намного быстрее, чем жесткие диски большого объема, которые используются для фактического хранения данных. Что еще более важно, SSD-диски намного дешевле, чем системная память. Большинство людей сравнивают стоимость SSD-дисков с ценой на жесткие диски, поэтому SSD-диски кажутся дорогими. Но по сравнению с системной памятью накопители SSD MLC на самом деле значительно дешевле.

Чтение из кэша

При чтении, данные, к которым идет наиболее частый доступ, помещаются в ARC, со временем он переполняется и данные из ARC вытесняются в L2ARC.

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

Накопители, выделяемые для L2ARC нет смысла объединять в RAID-массивы или иным образом резервируемые тома, поскольку с точки зрения ZFS отказ устройства L2ARC не является критичным. Вы просто добавляете каждое устройство в L2ARC по-отдельности.

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

Что следует помнить

Есть несколько аспектов, которые нужно помнить.

  • Диски L2ARC не зеркалируются. При добавлении дисков кэша нельзя настроить их как зеркальные, но в этом и нет необходимости, поскольку содержимое уже зеркально отражено на жестких дисках. Диски кэша являются просто недорогой альтернативой оперативной памяти для кэширования часто запрашиваемого контента.
  • В случае, если вы решите использовать накопители SSD вместо HDD для хранения данных, то диски кэша не нужны. Поскольку все накопители уже являются сверхбыстрыми SSD-дисками, использование дисков кэша не даст увеличения производительности.
  • Если вы планируете подключить большое количество накопителей SSD, рассмотрите использование нескольких контроллеров SAS. Если используется достаточное количество SSD-дисков, есть шанс перегрузить пропускную способность контроллера, что не позволит реализовать весь потенциал системы.

Эффективное кэширование в виртуальных средах

Вероятно, вы задаетесь вопросом, насколько эффективно двухуровневое кэширование для наиболее часто используемых данных в случае использования с виртуальными машинами? Повлияет ли кэш ARC и L2ARC на общую производительность?

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

Если вы планируете развернуть большое количество виртуальных машин, первым шагом создайте базовый шаблон, от которого будут порождаться тома виртуальных машин. Когда базовый шаблон готов, каждая дополнительная виртуальная машина должна создаваться на его основе. Технология виртуализации сохраняет изменения, специфичные для каждой виртуальной машины в разностном файле (например, QCOW2 с использованием backing file).

Когда решение для виртуализации реализовано таким образом, базовый шаблон будет эффективно кэшироваться в ARC (основной системной памяти). Это означает, что основные файлы операционной системы и файлы приложений будут обеспечивать производительность, близкую к уровню оперативной памяти. L2ARC сможет эффективно кэшировать наиболее часто используемый контент, который не будет задействован всеми виртуальными машинами, но будет содержать файлы и папки, например, с самых популярных веб-сайтов или баз данных. Самые редкие данные будут извлекаться с жестких дисков.

Настройка L2ARC в Linux

Для стабильной работы ZFS в Linux требуется ограничить параметры L2ARC, чтобы он не утилизировал больше памяти, чем требуется, иначе система может столкнуться с ситуацией нехватки памяти, что станет причиной нестабильной работы и зависаний системы. К сожалению, без данных настроек ZFS не в состоянии самостоятельно придерживаться разумного использования RAM в Linux.

По существу, необходимо определить несколько параметров для загружаемого модуля ZFS. Используйте для этого файл /etc/modprobe.d/zfs.conf, добавив в него несколько строк:

options zfs zfs_arc_min=536870912    # минимальный размер ARC в байтах
options zfs zfs_arc_max=20769803776  # максимальный размер ARC в байтах

В вышеуказанном примере для ZFS отводится не более чем 20GB RAM.

Так же, вы можете захотеть настроить некоторые параметры L2ARC. Приведем ряд полезных:

options zfs l2arc_noprefetch=0          # включить кэширование поточных данных (sequential io)

options zfs l2arc_write_max=26214400    # максимальная скорость записи в L2ARC

options zfs l2arc_write_boost=52428800  # boost скорости.

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

echo 20769803776 > /sys/module/zfs/parameters/zfs_arc_max

Экстренная очистка ARC при переполнении RAM

Иногда вы можете столкнуться с ситуацией, когда объем свободной RAM приближается к 0, хотя вы все настроили правильно. Возможно, что какое-то из приложений утилизировало больше памяти, чем вы рассчитали или просто драйвер ZFS «вылез» за границу разрешенной квоты памяти. В этом случае вам поможет простой подход, который очищает все кэши:

echo 3 > /proc/sys/vm/drop_caches

Вы можете даже добавить скрипт, который проверяет объем доступной свободной RAM и при снижении его ниже определенного порога (например, 1GB) будет вызывать очистку кэшей и уведомлять вас по E-mail. Ежеминутный вызов такого скрипта мониторинга вполне может повысить качество вашего сна, свободного времени на выходных и праздниках.

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