dimanche 12 mai 2024

zRAM, téléchargez de la RAM ! ou presque…

Vous souvenez-vous de ces pubs que l’on voyait sur nos navigateurs au début des années 2000 ? Celles qui nous proposaient de « télécharger de la RAM » ! Eh bien c’est devenu réalité (ou presque) avec zRAM !

zRAM est un module du noyau Linux qui augmente la performance d’un ordinateur en gérant une mémoire virtuelle (ou mémoire d’échange, swap en anglais) dans la mémoire vive (RAM) plutôt que sur le disque dur comme c’est traditionnellement le cas. Pour le dire autrement, zRAM utilise un peu de la RAM pour y stocker une mémoire d’échange compressée. Grace à la compression, l’espace occupé en mémoire correspond généralement au tiers de la mémoire allouée. Et c’est là toute l’astuce ! D’une part, l’accès à la mémoire vive est bien plus rapide qu’un accès disque, d’autre part la compression/décompression de la mémoire vive prenant moins de temps que l’utilisation du disque dur sous forme de mémoire virtuelle, cela permet d’augmenter la réactivité d’un système GNU/Linux.

Situation de départ

Pour éprouver les gains de performance promis par zRAM, j’ai sous la main le candidat idéal : la compilation de la police de caractères Iosevka dont je vous avais déjà parlé dans l’article « Ligatures dans le terminal ».

En l’état actuel des choses, disposant d’un processeur à 12 cœurs, et avec une partition d’échange de 3,8Go sur le disque dur, il me faut compiler cette police en limitant le nombre de processus concurrents (via l’option --jCmd 6) et en réduisant fortement la priorité de ce traitement grâce à la commande nice.

La commande qui me sert à compiler la police est donc la suivante :

nice -n 10 npm run build -- --jCmd=6 ttf::IosevkaCustom

Sans cela, le système gèle totalement pendant plusieurs minutes durant la compilation, avant d’être en mesure de me rendre la main.

Jouons avec zRAM

Tout d’abord, installons les outils nécessaires à la manipulation de zRAM.

sudo apt install zram-tools       # installation de zram

Dès lors, un périphérique zRAM est créé, comme on peut le voir avec la commande zramctl.

❯ sudo zramctl                   
NAME       ALGORITHM DISKSIZE   DATA COMPR  TOTAL STREAMS MOUNTPOINT
/dev/zram0 lzo-rle       256M     0B    0B     0B      12

Par défaut, il a une taille de 256Mo, ce qui est bien trop faible vu que nous disposons de 16Go de RAM. Supprimons donc ce périphérique, pour en créer un à notre convenance, disons de 8Go.

sudo zramctl --reset /dev/zram0   # suppression du périphérique zRAM par défaut
sudo zramctl --find --size 8G     # création d'un périphérique zRAM de 8Go

Voyons ce que cela donne :

❯ sudo zramctl                   
NAME       ALGORITHM DISKSIZE   DATA COMPR  TOTAL STREAMS MOUNTPOINT
/dev/zram0 lzo-rle         8G     0B    0B     0B      12

Parfait ! Il nous faut à présent faire de ce périphérique une mémoire d’échange, puis l’activer.

sudo mkswap /dev/zram0            # faire de ce périphérique une mémoire d'échange (swap)
sudo swapon -p 100 /dev/zram0     # activer la mémoire d'échange avec une priorité de 100
❯ sudo zramctl                   
NAME       ALGORITHM DISKSIZE   DATA COMPR  TOTAL STREAMS MOUNTPOINT
/dev/zram0 lzo-rle         8G     0B    0B     0B      12 [SWAP]

Nous avons à présent deux partitions swap : /dev/zram0 que nous venons d’activer, et /dev/dm-1 notre partition sur disque.

❯ sudo swapon
NAME       TYPE      SIZE   USED PRIO
/dev/zram0 partition 8,7G 590,5M  100
/dev/dm-1  partition 3,8G     0B   -2

Nous pouvons désactiver cette dernière pour que notre système ne soit pas tenté d’écrire sur cette partition.

sudo swapoff /dev/dm-1            # désactive la mémoire d'échange sur disque

Et voilà !

L’épreuve du feu

Faisons un test, et sans filet : levons toute limitation ! La commande que l’on s’apprête à lancer sera donc la suivante :

npm run build -- ttf::IosevkaCustom

Le résultat est probant ! La compilation de la police, qui auparavant saturait la mémoire, la swap et les processeurs en générant de trop nombreux accès disque, s’effectue dorénavant sans heurt, en 1min 51s. Alors oui ça swap ! Aux alentours de 570Mo (2.77G non compressés) sur les 8Go autorisés ; mais aucun gel d’écran, tout est fluide ! Et ce alors même que les limitations sur le nombre de processus parallèles autorisés et sur la priorité du traitement ont été levées ! Merveilleux !

Persistance

Nous avons constaté que zRAM tenait ses promesses, seulement voilà, ce que nous avons fait là ne sera pas persisté au redémarrage du système, à moins de nous y prendre un peu différemment.

Pour persister ces changements, il est nécessaire d’après la documentation de Debian, d’éditer le fichier /etc/default/zramswap ; dans notre cas comme suit :

# /etc/default/zramswap
SIZE=8192  
PRIORITY=100 

Nous pourrions aussi lui indiquer un pourcentage de mémoire vive utilisable par zRAM avec PERCENT (qui prendra le dessus sur SIZE) ; et pourquoi pas changer d’algorithme de compressions avec ALGO, pour opter par exemple pour zstd qui est annoncé comme plus rapide et offrant un meilleur taux de compression que lzo, l’algorithme par défaut. Attention cependant à vérifier que cet algorithme soit bien supporté par le système.

❯ sudo cat /sys/block/zram0/comp_algorithm
lzo [lzo-rle] lz4 lz4hc zstd

Une fois le fichier /etc/default/zramswap mis à jour et sauvegardé, il reste à redémarrer le service zramswap.

❯ sudo service zramswap reload

Enfin, pour éviter que la partition swap sur disque soit montée au démarrage, il suffit de commenter la ligne correspondante dans le fichier /etc/fstab et redémarrer le démon systemctl.

❯ sudo systemctl daemon-reload

Au prochain redémarrage, notre nouvelle mémoire d’échange zRAM sera activée et effective pour notre plus grand plaisir !

Bonus

Petit cadeau pour finir, il est possible de personnaliser le moniteur système htop pour lui faire afficher les accès disque, les accès réseau, ainsi que la consommation de la mémoire zRAM ! Tout cela depuis htop lui-même, sans avoir besoin d’éditer le fichier de configuration à la main ! Pressez la touche F2, et laissez-vous guider !