Подключение и настройка zRam-init в Calculate linux:
Применение zRam-init дает возможность более эффективно использовать возможности RAM по сравнению с обычным применением tmpfs в оперативной памяти.
zRam-init vs tmpfs: кратко:
| zRam-init | tmpfs | |
|---|---|---|
| Что делает | Сжимает редко используемую память (swap в RAM) | Хранит файлы в RAM |
| Сжатие | ||
| Расширение RAM | ||
| OOM-защита | ||
| Настройка | Автоматическая через 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%)** |
2 ГБ (25%) | 16 ГБ (200%) zstd | Используйте *disk-based portage ** |
| 16ГБ | 24 ГБ (150%) Слабый CPU | **32 ГБ (200%)** |
4 ГБ (25%) | 32 ГБ (200%) zstd | Рекомендуется disk-based portage ** |
| 24ГБ | 16 ГБ (75%) |
16 ГБ (75%) | 6 ГБ (25%) | 32 ГБ (150%) lz4 | |
| 32ГБ | 16 ГБ (50%) |
16 ГБ (50%) | 8 ГБ (25%) | 32 ГБ (100%) lz4 | |
| 64ГБ | 16 ГБ (25%) |
16 ГБ (25%) | 16ГБ (25%) | 64 ГБ (100%) lz4 |
ПОЯСНЕНИЯ К ТАБЛИЦЕ:
Когда использовать swap (zstd)?
ТОЛЬКО при 8-16 ГБ RAM — когда каждый мегабайт критичен
При 24+ ГБ: lz4 предпочтительнее — скорость важнее экономии
КРИТИЧЕСКИЕ ПРЕДОСТЕРЕЖЕНИЯ
Для 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 |
Тестирование:
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}'\'''