zRAM : Compresser la RAM au lieu de swapper sur Linux

zram



Introduction



zRAM est un module du noyau Linux présent depuis le noyau 2.6.37.
Il permet de compresser la RAM afin d'éviter de swapper sur le disque.
C'est plus performant de compresser/décompresser dans la RAM la RAM que d'écrire sur un disque mécanique ou SSD. Dans le cas du SSD, zRAM permet d'éviter d'user prématurément le SSD à cause des cycles d'écriture répétés lors du mécanisme de swapping.

Prérequis



Vérifier la config dans le noyau de CONFIG_ZRAM et CONFIG_ZRAM_WRITEBACK :


Code BASH :
grep ZRAM /boot/config-$(uname -r)



Code BASH :
CONFIG_ZRAM=m
CONFIG_ZRAM_WRITEBACK=y


Les "disques" zram seront vus comme des espaces de SWAP par le système.
Pour voir le détails des fichiers d'échange :

Code BASH :
cat /proc/swaps


Exemple sur mon système, avec un volume logique de 2Go :
Code BASH :
Filename                Type        Size    Used    Priority
/dev/dm-0                               partition    2097148    0    -2


Exemple sur une Ubuntu avec un fichier /swapfile :
Code BASH :
Filename                Type        Size    Used    Priority
/swapfile                               file        1435316    0    -2



Solution manuelle



La solution manuelle vous permet de prévoir un script à lancer au démarrage (ou non), et surtout de mettre le paramétrage souhaité.

Création et activation du ZRAM



Dans un premier temps, chargez le module zram :

Code BASH :
modprobe zram


Vérifiez qu'il est chargé :

Code BASH :
lsmod | grep zram


Retour si le module est actif :
Code BASH :
zram                   32768  0



Si on veut que le module se charge à chaque démarrage, on peut mettre le module dans un fichier de conf dans modprobe.d :
Code BASH :
echo "zram" > /etc/modprobe.d/zram.conf


Un dossier existe alors dans : /sys/block/zram0

Il contient toutes les informations / paramétrages de notre disque zram0.

Pour visualiser les algorithmes de compression :

Code BASH :
cat /sys/block/zram0/comp_algorithm


On va définir à zstd (plus performant) :

Code BASH :
echo zstd > /sys/block/zram0/comp_algorithm


Concernant la définition de la taille : pour un disque de 3Go, il faut indiquer la taille en octets
3 Gio => 3000 Mio => 3000000 Kio => 3000000000 o

Astuce :
Convertir un nombre de Mo en Octets :
Code BASH :
echo $(((3072*1024*1024)))

Convertir un nombre de Go en Octets :
Code BASH :
echo $(((3*1024*1024*1024)))


Code BASH :
echo 3000000000 > /sys/block/zram0/disksize


On fabrique le zram :
Code BASH :
mkswap -L zramswap /dev/zram0


On active le zram avec une priorité élevée (si fichier/partition swap existant, zram sera prioritaire avant le disque) :

Code BASH :
swapon -p 100 /dev/zram0


On vérifie que la prise en charge est correcte :

Code BASH :
cat /proc/swaps 

Code BASH :
Filename                Type        Size    Used    Priority
/dev/dm-0                               partition    2097148    0    -2
/dev/zram0                              partition    3283458    0    100


Désactivation et destruction du ZRAM



On désactive le zram ;
Code BASH :
swapoff /dev/zram0


On réinitialise les paramètres :
Code BASH :
echo 1 >/sys/block/zram0/reset


On peut retirer le module noyau :
Code BASH :
rmmod zram



Scripts de démarrage pour une solution automatique



Les scripts ici reprennent les commandes ci-dessus.
Ils permettent d'automatiser l'initialisation du zram au démarrage du système et de les désactiver à l'arrêt.

OpenRC



On créé notre script OpenRC :

Code BASH :
vi /etc/init.d/zram


Code BASH :
#!/sbin/openrc-run
depend()
{
    after clock root swap
    before localmount
    keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -vserver
}
start()
{
    ebegin "Activation de ZRAM"
    # Charge le module
    modprobe zram
    # Compression ZSTD
    echo zstd > /sys/block/zram0/comp_algorithm
    # Taille 3Go
    echo 3221225472 > /sys/block/zram0/disksize
    # Création ZRAM
    mkswap -L zramswap /dev/zram0
    # Activation ZRAM
    swapon -p 100 /dev/zram0
    # Fin
    eend 0
}
stop()
{
    # Désactivation ZRAM
    swapoff /dev/zram0
    # Reset du ZRAM
    echo 1 >/sys/block/zram0/reset
    # Suppression du module
    rmmod zram
    # Fin
    eend 0
}


On le rend exécutable :

Code BASH :
chmod +x /etc/init.d/zram


On peut gérer notre script avec les commandes suivantes ( Démarrage, Arrêt, Activation, Désactivation) :

Code BASH :
/etc/init.d/zram start
/etc/init.d/zram stop
rc-update add zram
rc-update del zram


Systemd



On créé notre script SystemD :

Code BASH :
vi /etc/systemd/system/zram.service


Code BASH :
[Unit]
Description=Service ZRAM
[Service]
ExecStart=/usr/local/bin/zram-start
ExecStop=/usr/local/bin/zram-stop
Type=oneshot
RemainAfterExit=true
[Install]
WantedBy=multi-user.target



On créé nos 2 scripts zram-start et zram-stop :

Code BASH :
vi /usr/local/bin/zram-start


Code BASH :
#! /bin/bash
# Charge le module
modprobe zram
# Compression ZSTD
echo zstd > /sys/block/zram0/comp_algorithm
# Taille 3Go
echo 3221225472 > /sys/block/zram0/disksize
# Création ZRAM
mkswap -L zramswap /dev/zram0
# Activation ZRAM
swapon -p 100 /dev/zram0


On le rend exécutable :

Code BASH :
chmod +x /usr/local/bin/zram-start


On fait de même pour le stop :

Code BASH :
vi /usr/local/bin/zram-stop


Code BASH :
#! /bin/bash
# Désactivation ZRAM
swapoff /dev/zram0
# Reset du ZRAM
echo 1 >/sys/block/zram0/reset
# Suppression du module
rmmod zram


On le rend exécutable :
Code BASH :
chmod +x /usr/local/bin/zram-stop


On recharge le démon systemd :
Code BASH :
systemctl --system daemon-reload


On peut gérer notre script avec les commandes suivantes ( Démarrage, Arrêt, Activation, Désactivation) :

Code BASH :
systemctl start zram
systemctl stop zram
systemctl enable zram
systemctl disable zram



Solutions livrées avec les distributions




Fedora



On installe le paquet zram (en principe, installé par défaut) :

Code BASH :
dnf install zram


Comme d'habitude, chez Fedora/RHEL, les services sont désactivés et non lancés après installation.

On va activer et démarrer le service zram-swap.service :

Code BASH :
systemctl enable zram-swap.service
systemctl start zram-swap.service


Il existe un fichier de config pour régler la taille /etc/zram.conf :

Code BASH :
vi /etc/zram.conf


FACTOR est le ratio de 1/n de la RAM. Par défaut Factor vaut 2 donc le disque fait la moitié de la RAM. Nombre entier, pas possible de faire plus que la RAM (valeur 1)

Code BASH :
FACTOR = 2 


Debian et Ubuntu



On installe le paquet zram-tools :

Code BASH :
apt install zram-tools 


Un service est disponible démarré et activé de suite.
Il s'appelle zramswap.service.

Il est possible de personnaliser le service via le fichier /etc/default/zramswap

Code BASH :
vi /etc/default/zramswap


On peut définir la taille en fonction d'un pourcentage de la RAM. Exemple avec une taille de 100% de la RAM :

Code BASH :
PERCENTAGE=100



Commandes de vérification



Voici quelques commandes pour avoir des infos sur zram.

swapon -s permet de lister les fichiers d'éhange :

Code BASH :
swapon -s


Code BASH :
Nom de fichier                Type        Taille    Utilisé    Priorité
/dev/dm-0                                  partition    2097148    0    -2
/dev/zram0                                 partition    3283458    0    100


La commande zramctl permet d'afficher des infos :

Code BASH :
NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd         3.0G   4K   66B    4K      12 [SWAP]


Et de manière détaillée :

Code BASH :
zramctl --output-all 
NAME       DISKSIZE DATA COMPR ALGORITHM STREAMS ZERO-PAGES TOTAL MEM-LIMIT MEM-USED MIGRATED MOUNTPOINT
/dev/zram0    3.0G   4K   66B zstd           12          0    4K        0B       4K       0B [SWAP]


Il est possible avec zramctl de gérer ses disques zram au lieu d'écrire dans les fichiers comme ci-dessus.