Подключение и настройка zRam-init в Calculate Linux

Подключение и настройка zRam-init в Calculate linux:

Применение zRam-init дает возможность более эффективно использовать возможности RAM по сравнению с обычным применением tmpfs в оперативной памяти.

zRam-init vs tmpfs: кратко:

zRam-init tmpfs
Что делает Сжимает редко используемую память (swap в RAM) Хранит файлы в RAM
Сжатие :white_check_mark: Да, прозрачное :cross_mark: Нет
Расширение RAM :white_check_mark: До 2-3× фактической памяти :cross_mark: Фиксированный размер
OOM-защита :white_check_mark: Предотвращает зависания :cross_mark: Риск исчерпания памяти
Настройка Автоматическая через init-скрипт Ручная для каждой точки монтирования

Использование zRam-init дает возможность компиляции тяжелых пакетов, таких как Chronium, в оперативной памяти объемом 8Gb (в частности мне это удалось).

Перед установкой:

Отключим дефолтный zRam:

rc-update del zram boot
rc-service zram stop

Переименуем файлы /etc/conf.d/zram и /etc/init.d/zram, если вдруг вы захотите вернуть все обратно:

mv /etc/conf.d/zram /etc/conf.d/zram.back
mv /etc/init.d/zram /etc/init.d/zram.back

Установка zram-init:

Добавим нестабильную версию пакета sys-block/zram-init пока 13 версия пакета не вошла в стабильную ветку:

echo "sys-block/zram-init ~amd64" >> /etc/portage/package.accept_keywords/custom

Установим пакет:

emerge -av sys-block/zram-init

Настройка:

Отредактировать файл настроек ==/etc/conf.d/zram-init ==:

mcedit /etc/conf.d/zram-init

Привести в соответствие:
Пример конфигурации (создаёт 3 устройства)

# SPDX-License-Identifier: GPL-2.0-only
# Optimized for Calculate Linux with 16GB RAM

# === ОБЩИЕ ПАРАМЕТРЫ ===
# load zram kernel module on start?
load_on_start="yes"
# unload zram kernel module on stop?
unload_on_stop="no"         # ВАЖНО: "no"
# Number of devices.
# This value is also passed to the kernel module on modprobe.
num_devices="4"             # ВАЖНО: 3 устройства, как в вашем файле + Ramdisk

# === УСТРОЙСТВО 0: SWAP (32 ГБ) ===
type0="swap"
flag0=""                    # Используем дефолтный приоритет 16383
size0="32768"               # 16ГБ × 200% = 32768 МБ
# size0=`LC_ALL=C free -m | awk '/^Mem:/{print int($2 * ПРОЦЕНТ / 100)}'`
mlim0=""                    # Без ограничения памяти
back0=""                    # Без backup устройства
icmp0=""                    # Не записывать несжимаемые страницы
idle0=""                    # Не записывать idle страницы
wlim0=""                    # Без лимита writeback
notr0=""                    # Использовать discard (по умолчанию)
algo0="lz4"                 # Для swap, если нужна СКОРОСТЬ lz4, сжатие zstd
para0=""                    # Без параметров алгоритма
labl0="zram_swap"           # Метка для удобства
uuid0=""                    # Без фиксации UUID
args0=""                    # Дополнительных аргументов нет

# === УСТРОЙСТВО 1: /tmp (4 ГБ) ===
type1="/tmp"
flag1="ext4"                # Файловая система
size1="4096"                # 4ГБ для /tmp
mlim1=""
back1=""
icmp1=""
idle1=""
wlim1=""
blck1=""
irat1=""                    # Авто-расчёт inode
inod1=""                    # Авто-расчёт inode
opts1="noatime,nodiratime"  # Если нужно безопасность"noatime,nodiratime,nosuid,nodev"
mode1="1777"                # Права /tmp (sticky bit)
owgr1=""                    # root:root по умолчанию
notr1=""
algo1="lz4"                 # Для /tmp используем lz4 (скорость)
para1=""
labl1="zram_tmp"            # Метка для удобства
uuid1=""
args1=""

# === УСТРОЙСТВО 2: /var/calculate/tmp/portage (16 ГБ) ===
type2="/var/calculate/tmp/portage"
flag2="ext4"
size2="32768"               # 16ГБ x 200% = 32768 МБ для компиляции
# size2=`LC_ALL=C free -m | awk '/^Mem:/{print int($2 * ПРОЦЕНТ / 100)}'`
mlim2=""
back2=""                    # Можно добавить SSD для несжимаемых данных, если нужно
icmp2=""                    # Писать несжимаемые на backup
idle2=""                    # Писать idle страницы на backup
wlim2=""
blck2=""
irat2=""
inod2=""
opts2="noatime,nodiratime"  # Если нужно безопасность"noatime,nodiratime,nosuid,nodev"
mode2="755"                 # Безопасные права (не 1777!)
owgr2="portage:portage"     # КРИТИЧНО: владелец portage
notr2=""
algo2="zstd"                # Для исходников zstd лучше
para2="level=3"             # Уровень сжатия 3 (оптимально)
labl2="zram_portage"        # Метка для удобства
uuid2=""
args2=""


# === УСТРОЙСТВО 3: /mnt/ramdisk (4 ГБ) ===
type3="/mnt/ramdisk"
flag3="ext4"                # Файловая система
size3="4096"                # 4ГБ для /mnt/ramdisk
mlim3=""
back3=""
icmp3=""
idle3=""
wlim3=""
blck3=""
irat3=""                    # Авто-расчёт inode
inod3=""                    # Авто-расчёт inode
opts3="noatime,nodiratime"  # Если нужно безопасность"noatime,nodiratime,nosuid,nodev"
mode3="1777"                # Права /tmp (sticky bit)
owgr3=""                    # root:root по умолчанию
notr3=""
algo3="lz4"                 # Для /tmp используем lz4 (скорость)
para3=""
labl3="zram_ramdisk"        # Метка для удобства
uuid3=""
args3=""

Для того чтобы нормально запускалась сессия wayland и инициализация type0=“swap”,
нужно отредактировать файл ==/etc/init.d/zram-init ==:
Заменить функцию *depend * на:

depend() {
   after clock root 
   before localmount swap
}

Заменить функцию *ZramStop * на:

ZramStop() {
    if [ x"$fstype" = x'swap' ]; then
        einfo "Remove zram$2 swap"
        zram-init ${1+"$@"} -- 0 2>/dev/null || true
    else
        einfo "Umount zram$2 $fstype"
        zram-init ${1+"$@"} -- 0 "$fstype" 2>/dev/null || true
    fi
    eend 0
}

Добавьте в автозапуск:

#

rc-update add zram-init boot
rc-service zram-init start

Таблица размера zRam устройств в зависимости от размера ОЗУ:

RAM swap (lz4) swap (zstd) /tmp (lz4) /var/calculate/tmp/portage Замечания
8 ГБ 12 ГБ (150%) Слабый CPU **16 ГБ (200%)**:white_check_mark:Предпочтительней 2 ГБ (25%) 16 ГБ (200%) zstd Используйте *disk-based portage **
16ГБ 24 ГБ (150%) Слабый CPU **32 ГБ (200%)**:white_check_mark:Предпочтительней 4 ГБ (25%) 32 ГБ (200%) zstd Рекомендуется disk-based portage **
24ГБ 16 ГБ (75%):white_check_mark:Предпочтительней 16 ГБ (75%) 6 ГБ (25%) 32 ГБ (150%) lz4
32ГБ 16 ГБ (50%):white_check_mark:Предпочтительней 16 ГБ (50%) 8 ГБ (25%) 32 ГБ (100%) lz4
64ГБ 16 ГБ (25%):white_check_mark:Предпочтительней 16 ГБ (25%) 16ГБ (25%) 64 ГБ (100%) lz4

:open_book: ПОЯСНЕНИЯ К ТАБЛИЦЕ:

Когда использовать swap (zstd)?

:white_check_mark: ТОЛЬКО при 8-16 ГБ RAM — когда каждый мегабайт критичен
При 24+ ГБ: lz4 предпочтительнее — скорость важнее экономии

:warning: КРИТИЧЕСКИЕ ПРЕДОСТЕРЕЖЕНИЯ

Для 8 ГБ RAM: *

  • RISK OOM: 90% — сборка Chromium скорее всего упадёт
  • Рекомендация: Обязательно используйте disk-based portage для сборки тяжёлых пакетов (см. Настройка package.env)

Для 16 ГБ RAM: **

  • RISK OOM: 10%можно собрать Chromium
  • Запретите: Браузер, Telegram, Discord во время сборки
  • Рекомендация: Для комфортной работы используйте disk-based portage для сборки тяжёлых пакетов (см. Настройка package.env)

Важные настройки для Calculate linix, Gentoo:

Добавьте в /etc/sysctl.d/99-zram.conf для любого объема RAM:

vm.swappiness=100
vm.watermark_scale_factor=125
vm.page-cluster=0

Почему это важно для zram:

  • vm.swappiness=100: Заставляет ядро активно использовать zram вместо дискового swap. Без этого zram будет использован только в крайнем случае.
  • vm.watermark_scale_factor=125: Ускоряет запуск swap при заполнении RAM, что важно для компиляции в Gentoo.
  • vm.page-cluster=0: Уменьшает задержки при страничных fault’ах в zram.

ОПЦИОНАЛЬНО: снижаем задержки записи

  • dirty_ratio=15: Процессы начинают блокироваться при заполнении 15% RAM грязными данными → меньше задержек, но больше активности записи.
  • dirty_background_ratio=5: Фоновый сброс начинается при 5% → данные пишутся плавнее.
  • vm.vfs_cache_pressure=100: Этот параметр управляет агрессивностью сброса VFS кеша (inode и dentry) при нехватке памяти.

Проверка zRam устройств:

#

# Показывает все zram устройства, размер, использование, алгоритм
zramctl

# Показывает примонтированные файловые системы zram
mount | grep zram

# Показывает swap-разделы (включая zram)
swapon --show
# или
cat /proc/swaps

# Проверить сами устройства
ls -l /dev/zram*


Компиляция тяжелых пакетов в zRam:

Настройка package.env. Сборка тяжёлых пакетов в zRam:

#

mkdir -p /etc/portage/env && cat > /etc/portage/env/heavy-packages.conf << 'EOF'
PORTAGE_TMPDIR="/var/calculate/tmp"
MAKEOPTS="-jN -lM"
EMERGE_DEFAULT_OPTS="--jobs 1"
EOF
Подставить параметры `MAKEOPTS="-jN -lM"` из таблицы: "Настройка MAKEOPTS и load average для компиляции тяжелых пакетов:"

#

mkdir -p /etc/portage/package.env && cat > /etc/portage/package.env/heavy-packages << 'EOF'
app-office/libreoffice        heavy-packages.conf
dev-lang/ghc                  heavy-packages.conf
dev-lang/mono                 heavy-packages.conf
dev-lang/rust                 heavy-packages.conf
dev-lang/spidermonkey         heavy-packages.conf
mail-client/thunderbird       heavy-packages.conf
sys-devel/clang               heavy-packages.conf
sys-devel/gcc                 heavy-packages.conf
sys-devel/llvm                heavy-packages.conf
www-client/chromium           heavy-packages.conf
www-client/firefox            heavy-packages.conf
sys-kernel/gentoo-kernel      heavy-packages.conf
net-libs/webkit-gtk           heavy-packages.conf
EOF

Настройка package.env. Сборка тяжёлых пакетов на диске при ограниченной RAM <16 Gb:

#

mkdir -p /etc/portage/env && cat > /etc/portage/env/notzram.conf << 'EOF'
PORTAGE_TMPDIR="/var/calculate/tmp/notzram"
MAKEOPTS="-jN -lM"
EMERGE_DEFAULT_OPTS="--jobs 1"
EOF

#

mkdir /var/calculate/tmp/notzram
chown portage:portage /var/calculate/tmp/notzram
chmod 775 /var/calculate/tmp/notzram 

#

mkdir -p /etc/portage/package.env && cat > /etc/portage/package.env/notzram << 'EOF'
app-office/libreoffice        notzram.conf
dev-lang/ghc                  notzram.conf
dev-lang/mono                 notzram.conf
dev-lang/rust                 notzram.conf
dev-lang/spidermonkey         notzram.conf
mail-client/thunderbird       notzram.conf
sys-devel/clang               notzram.conf
sys-devel/gcc                 notzram.conf
sys-devel/llvm                notzram.conf
www-client/chromium           notzram.conf
www-client/firefox            notzram.conf
sys-kernel/gentoo-kernel      notzram.conf
net-libs/webkit-gtk           notzram.conf
EOF

Настройка MAKEOPTS и load average для компиляции тяжелых пакетов:

Для Calculate linux данные настройки не критичны, так как он является бинарным дистрибутивом. По умолчанию MAKEOPTS=“-jN” в /etc/portage/make.conf/custom ==(make.conf)== где N=количеству потоков CPU+1. Но если нужна компиляция тяжелых пакетов, таких как chromium, webkit-gtk и др. потребуется нижеследующая оптимизация:

Матрица оптимальных параметров MAKEOPTS для Portage

CPU \ RAM 8 GB 16 GB 24 GB 32 GB 64 GB 128 GB 256 GB
4 -j4 -l3 -j4 -l3 -j4 -l3 -j4 -l3 -j4 -l3 -j4 -l3 -j4 -l3
6 -j4 -l3 -j6 -l4 -j6 -l4 -j6 -l4 -j6 -l4 -j6 -l4 -j6 -l4
8 -j4 -l3 -j8 -l6 -j8 -l6 -j8 -l6 -j8 -l6 -j8 -l6 -j8 -l6
12 -j4 -l3 -j8 -l6 -j12 -l9 -j12 -l9 -j12 -l9 -j12 -l9 -j12 -l9
16 -j4 -l3 -j8 -l6 -j12 -l9 -j16 -l12 -j16 -l12 -j16 -l12 -j16 -l12
24 -j4 -l3 -j8 -l6 -j12 -l9 -j16 -l12 -j24 -l18 -j24 -l18 -j24 -l18
32 -j4 -l3 -j8 -l6 -j12 -l9 -j16 -l12 -j32 -l24 -j32 -l24 -j32 -l24
64 -j4 -l3 -j8 -l6 -j12 -l9 -j16 -l12 -j32 -l24 -j64 -l48 -j64 -l48
128 -j4 -l3 -j8 -l6 -j12 -l9 -j16 -l12 -j32 -l24 -j64 -l48 -j128 -l96
K = 0.75   [коэффициент производительности: отзавчивость 0.75 рекомендации Gentoo 0.9]
N = min(CPU_threads, RAM_GB / 2)  [округление вниз]
M = round(N × K)               [load average]
MAKEOPTS="-jN -lM"

Матрица MAKEOPTS для компиляции “тяжелых” пакетов (llvm, rust, chromium)

CPU \ RAM 8 GB 16 GB 24 GB 32 GB 64 GB 128 GB 256 GB
4 -j3 -l2 -j3 -l2 -j3 -l2 -j3 -l2 -j3 -l2 -j3 -l2 -j3 -l2
6 -j3 -l2 -j4 -l3 -j4 -l3 -j4 -l3 -j4 -l3 -j4 -l3 -j4 -l3
8 -j3 -l2 -j6 -l4 -j6 -l4 -j6 -l4 -j6 -l4 -j6 -l4 -j6 -l4
12 -j3 -l2 -j6 -l4 -j9 -l7 -j9 -l7 -j9 -l7 -j9 -l7 -j9 -l7
16 -j3 -l2 -j6 -l4 -j9 -l7 -j12 -l9 -j12 -l9 -j12 -l9 -j12 -l9
24 -j3 -l2 -j6 -l4 -j9 -l7 -j12 -l9 -j18 -l14 -j18 -l14 -j18 -l14
32 -j3 -l2 -j6 -l4 -j9 -l7 -j12 -l9 -j24 -l18 -j24 -l18 -j24 -l18
64 -j3 -l2 -j6 -l4 -j9 -l7 -j12 -l9 -j24 -l18 -j48 -l36 -j48 -l36
128 -j3 -l2 -j6 -l4 -j9 -l7 -j12 -l9 -j24 -l18 -j48 -l36 -j96 -l72
K = 0.75   [коэффициент производительности: отзавчивость 0.75 рекомендации Gentoo 0.9]
N = (min(CPU_threads, RAM_GB / 2)) × 3/4  [округление вниз]
M = round(N × K)                           [load average]
MAKEOPTS="-jN -lM"

Примеры расчета:

Конфигурация Расчет Результат
16 потоков, 32 ГБ RAM N = min(16, 32/2) = min(16, 32) = 16M = 16 × 0.75 = 12.0 -j16 -l12.0
32 потоков, 32 ГБ RAM N = min(32, 32/2) = min(16, 16) = 16M = 16 × 0.75 = 12.0 -j16 -l12.0
32 потоков, 32 ГБ RAM (heavy-packadges) N = (min(128, 256/2)) × 0.75 = (min(32, 16)) × 0.75 = 12М = 12 × 0.75 = 9 -j12 -l9.0

Тестирование:

  • Тестируйте с MAKEOPTS="-jN -lM" emerge <пакет> и htop+uptime.

FEATURES="-getbinpkg" MAKEOPTS="-jN -lM" emerge -av <пакет>

Мониторинг компиляции:

При помощи утилит top, htop, btop:

htop

Статистика в реальном времени (если используется app-portage/portage-utils)

qlop -r  # показывает текущую сборку и оставшееся время

Для постоянного обновления каждую секунду:

watch -n 1 qlop -r

Более информативно:

watch -c -n 1 'echo -e "\n\033[1;32m>>> QLOP - Текущие сборки:\033[0m"; qlop -r; echo; echo -e "\033[1;33m>>> Активные компиляторы (потоки/время):\033[0m"; ps -eo pid,cmd,nlwp,etimes --sort=-etimes | awk '\''/gcc|clang|g\+\+/{printf "  \033[0;32m%-7s\033[0m \033[1;34m%-40s\033[0m \033[0;35mпотоков:%2s\033[0m \033[0;36mвремя:%5ss\033[0m\n", $1, substr($0, index($0,$2)), $(NF-1), $NF}'\'''

Статистика в реальном времени (если используется app-portage/genlop):
Установите пакет app-portage/genlop:

emerge -av app-portage/genlop

Мониторинг:

genlop -c

Для постоянного обновления каждую секунду:

watch --color -n 1 'genlop -c'

Более информативно:

watch -c -n 1 'echo -e "\n\033[1;32m>>> GENLOP - Прогресс сборки:\033[0m"; genlop -c; echo; echo -e "\033[1;33m>>> Активные процессы компиляции (CPU threads):\033[0m"; ps -eo pid,cmd,nlwp,etimes --sort=-etimes | awk '\''/gcc|clang|g\+\+/{printf "  \033[0;32m%-7s\033[0m \033[1;34m%-40s\033[0m \033[0;35mпотоков: %2s\033[0m \033[0;36mвремя: %5ss\n", $1, substr($0, index($0,$2)), $(NF-1), $NF}'\'''
1 Like

Чтобы случайно или по неосмотрительности не перезаписать конфигурационные файлы при применении dispatch-conf или etc-update при обновлениях, можно создать шаблон с расширением .clt:

cp /etc/init.d/zram-init /etc/init.d/zram-init.clt
cp /etc/conf.d/zram-init /etc/conf.d/zram-init.clt

Супер! Отличная работа!
Только это не замена tmpfs, это замена кальковского zram.

Но пркрайне мере вместо tmpfs, все это добро такое как tmp, /var/calculete/tmp/portage ну и даже ramdisk в RAM запихать с сжатием это здорово. Особенно /var/calculete/tmp/portage, при правильных настройках MAKEOPTS=“-jN -lM” даже swap может не пригодиться при компиляции. Особено zRam-init полезен в виртуалке с gentoo с небольшими правками. ))

Я не про это. А про то, что пост о замене кальковского zram на гентушный zram-init. Я тоже его меняю. Разговор же про swap.
tmpfs отдельно.

Гентушный zRam-init по умолчанию косячный. Долго мне пришлось копаться чтобы его более мение до ума довести. ))