zram (Русский)
zram, ранее известный как compcache, — это модуль ядра Linux, позволяющий создать сжатое блочное устройство в ОЗУ, то есть RAM-диск со сжатием на лету. Создаваемое этим модулем блочное устройство можно использовать в качестве подкачки или как обычный RAM-диск. Чаще всего zram используется для хранения временных файлов (/tmp
) и для подкачки. Изначально zram выполнял только последнюю функцию, отсюда и первоначальное название «compcache» («compressed cache»).
Использование в качестве подкачки
Изначально созданное блочное устройство zram не резервирует и не использует оперативную память. Лишь в момент переноса страниц памяти в подкачку они будут сжиматься и помещаться в блочное устройство zram. Размер этого устройства увеличивается и уменьшается динамически по мере необходимости.
Даже если предположить, что zstd будет достигать не самого высокого коэффициента сжатия 1:2 (на реальных данных коэффициент сжатия обычно около 1:3), использование zram позволит поместить в оперативную память больше данных, чем без сжатия.
- При настройке zram размер устройства zram определяет максимальный объем хранимых данных без учёта сжатия. Вы можете задать размер zram равный объёму оперативной памяти или даже больше, если данные смогут в поместиться в память в сжатом виде.
- Если в используемом вами ядре по умолчанию включен zswap, его стоит отключить, чтобы он не работал как кэш подкачки перед zram. Включение их обоих также приводит к отображению некорректной статистики в zramctl(8), и zram остаётся в основном неиспользуемым, потому что zswap перехватывает и сжимает страницы памяти до того как они попадут в zram.
- Спящий режим не может работать с устройством zram, даже если zram настроен на использование резервного устройства в постоянной памяти; logind не позволит перейти в спящий режим, если подкачка находится на устройстве zram.
mem_limit
можно указать максимальный объём памяти, который ZRAM может использовать для хранения сжатых данных.Для начала в качестве размера устройства zram можно указать половину объёма оперативной памяти.
Вручную
Чтобы добавить одно устройство zram со сжатием zstd, ёмкостью в половину объёма оперативной памяти и приоритетом выше обычного (только для текущего сеанса):
# modprobe zram # zramctl /dev/zram0 --algorithm zstd --size "$(($(grep -Po 'MemTotal:\s*\K\d+' /proc/meminfo)/2))KiB" # mkswap -U clear /dev/zram0 # swapon --discard --priority 100 /dev/zram0
Для выключения можно перезагрузиться или выполнить
# swapoff /dev/zram0 # modprobe -r zram # echo 1 > /sys/module/zswap/parameters/enabled
Подробное объяснение всех шагов, опций и потенциальных проблем описано в официальной документации модуля zram.
Чтобы сделать устройство zram постоянным, используйте один из описанных ниже методов.
С использованием правила udev
Пример ниже показывает, как настроить подкачку на zram автоматически при загрузке с помощью одного правила udev. Для этого не требуется дополнительных пакетов.
Сперва включите автоматическую загрузку модуля:
/etc/modules-load.d/zram.conf
zram
Создайте правило udev, изменив disksize
по необходимости:
/etc/udev/rules.d/99-zram.rules
ACTION=="add", KERNEL=="zram0", ATTR{comp_algorithm}="zstd", ATTR{disksize}="4G", RUN="/usr/bin/mkswap -U clear /dev/%k", TAG+="systemd"
Добавьте /dev/zram
в файл fstab с приоритетом выше стандартного:
/etc/fstab
/dev/zram0 none swap defaults,discard,pri=100 0 0
/dev/disk/by-label/*
и /dev/disk/by-uuid/*
для устройств zram.С использованием zram-generator
zram-generator предоставляет юнит systemd-zram-setup@.service
для автоматической инициализации устройства zram без необходимости включать/запускать шаблон или его экземпляры. Смотрите zram-generator(8) и zram-generator.conf(5).
Для использования установите пакет zram-generator и создайте такой файл настроек:
/etc/systemd/zram-generator.conf
[zram0] zram-size = min(ram / 2, 4096) compression-algorithm = zstd
zram-size
— размер устройства zram в МиБ. Можно написать ram
, чтобы в качестве значения использовать объём оперативной памяти.
compression-algorithm
задаёт алгоритм сжатия, используемый устройством zram. Посмотреть список доступных алгоритмов можно с помощью команды cat /sys/block/zram0/comp_algorithm
(текущий используемый алгоритм выделен квадратными скобками).
Включать юниты не нужно, они будут запускаться автоматически после перезагрузки. Чтобы запустить их без перезагрузки, выполните daemon-reload и запустите systemd-zram-setup@zramN.service
, где N
соответствует нумерации настроенных вами устройств zram (для приведённого выше примера настроек это systemd-zram-setup@zram0.service
).
Вы можете проверить статус подкачки на настроенном вами устройстве /dev/zramN
, посмотрев статус экземпляра юнита systemd-zram-setup@zramN.service
или с помощью команды zramctl(8) или swapon(8).
С использованием zramswap
zramswapAUR предоставляет автоматический скрипт для настройки подкачки высоким приоритетом и размером по умолчанию 20% от размера ОЗУ вашей системы. Чтобы он запускался автоматически при каждой загрузке, включите службу zramswap.service
.
С использованием zramd
zramdAUR[ссылка недействительна: package not found] позволяет автоматически настроить zram с использованием сжатия zstd по умолчанию. Настройки можно изменить в файле /etc/default/zramd
. Чтобы он запускался автоматически при каждой загрузке, включите службу zramd.service
.
Советы и рекомендации
Просмотр статистики zram
Используйте команду zramctl(8). Пример:
$ zramctl
NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT /dev/zram0 zstd 32G 1.9G 318.6M 424.9M 16 [SWAP]
- DISKSIZE = 32G: это устройство zram может хранить до 32 ГиБ данных (без учёта сжатия).
- DATA = 1.9G: на данный момент этом устройстве zram хранится 1,9 ГиБ данных (без учёта сжатия).
- COMPR = 318.6M: 1,9 ГиБ несжатых данных были сжаты до 318,6 МиБ.
- TOTAL = 424.9M: для хранения 1,9 ГиБ несжатых данных в устройстве zram понадобилось 424,9 МиБ памяти с учётом метаданных.
Несколько устройств zram
По умолчанию модуль ядра zram
при загрузке создаёт одно устройство /dev/zram0
.
Чтобы создать несколько устройств, укажите параметр модуля ядра num_devices
. Также можно создавать их на лету без перезагрузки модуля.
Оптимизация подкачки на устройстве zram
Поскольку устройство zram отличается от подкачки на обычном диске, можно оптимизировать настройки подкачки для zram:
/etc/sysctl.d/99-vm-zram-parameters.conf
vm.swappiness = 180 vm.watermark_boost_factor = 0 vm.watermark_scale_factor = 125 vm.page-cluster = 0
Эти параметры используются в Pop!_OS и основаны на результатах тестирования некоторыми пользователями в r/Fedora, где выяснилось, что vm.page-cluster = 0
работает идеально. Также хорошо работают высокие значения swappiness, что предлагается документацией ядра:
- Значение по умолчанию — 60.
- Для подкачки в памяти, такой как zram или zswap, а также гибридных установок, в которых подкачка расположена на более быстрых устройствах, чем файловая система, можно рассматривать к использованию значения, превышающие 100. Например, если случайный ввод-вывод на устройстве подкачки в среднем в 2 раза быстрее, чем ввод-вывод из файловой системы, swappiness может иметь значение 133 (x + 2x = 200, 2x = 133.33).
В системе с жёстким диском случайный ввод-вывод с устройства zswap будет на порядки быстрее, чем ввод-вывод с файловой системы, поэтому значение swappiness лучше установить ~200. Даже в системе с быстрым SSD большое значение swappiness может быть хорошо.
Подключение резервного устройства для zram
zram можно настроить так, чтобы при нехватке памяти несжимаемые страницы вытеснялись на указанное блочное устройство.
Чтобы добавить такое устройство вручную:
# echo /dev/sdX > /sys/block/zram0/backing_dev
Если вы используете zram-generator, отредактируйте файл /etc/systemd/zram-generator.conf
, указав путь к нужному устройству в соответствующем разделе [zramX]
:
/etc/systemd/zram-generator.conf
writeback-device=/dev/disk/by-partuuid/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
Использование zram не для подкачки
zram также можно использовать в качестве обычного блочного устройства, аналогичного /dev/ram
, но использующего меньше физической памяти за счёт небольшого снижения производительности. Однако здесь есть несколько оговорок:
- нет поддержки таблицы разделов (нет автоматического создания
/dev/zramxpy
); - размер блока фиксирован и составляет 4 КиБ.
Очевидный способ обойти это — создать loop-устройство поверх zram с помощью losetup, указав желаемый размер блока с помощью опции -b
и используя опцию -P
для обработки таблицы разделов и автоматического создания устройств, соответствующих разделам на loop-устройстве. Сперва добавьте устройство zram нужного размера:
# zramctl -f -s NG
/dev/zramx
Затем, если вы хотите использовать на нём какой-то образ диска, запишите его содержимое на новое устройство /dev/zramx
, после чего создайте loop-устройство. Имейте в виду, что если на образе диска есть таблица разделов, то размер блока loop-устройства должен совпадать с размером блока, который используется в этой таблице разделов (обычно это 512).
# losetup -f -b 512 -P /dev/zramx
# ls /dev/loop*
/dev/loop0 /dev/loop0p1 /dev/loop0p2
# mount /dev/loop0p1 /mnt/boot # mount /dev/loop0p2 /mnt/root
- Номер устройства zram зависит от наличия ранее добавленных устройств zram, а его размер должен быть достаточным для того, чтобы в нём поместился нужный вам образ диска.
- Вывод команды
ls /dev/loop*
зависит от количества разделов, присутствующих в записанном вами образе диска.