veilletech.fr
28 août Feed du jour
#10 LINUX Article

zram et oomd : un petit VPS qui ne rame plus

Le swap n'est pas de la RAM d'urgence, c'est un réglage.

Sur un VPS de 1 à 8 Go, la saturation mémoire se traduit par un thrashing qui rend la machine injoignable avant tout OOM kill. Un swap compressé en RAM (zram) et une décision d'éviction pilotée par la pression (systemd-oomd) évitent les deux, avec quatre fichiers de configuration.

3 min de lecturevidéo 1:15
Partager
Sommaire4 sections
  1. Ce qui se passe
  2. Comment s'y prendre
  3. Vérifier
  4. À retenir

Ce qui se passe

Quand une petite machine arrive au bout de sa mémoire, elle ne meurt pas proprement. Elle passe de longues minutes à faire des allers-retours entre les pages anonymes et un swap sur disque lent, le cache de fichiers s'effondre, SSH devient pâteux — et le tueur OOM du noyau ne se déclenche qu'après.

Deux outils traitent chacun une moitié du problème : zram, un périphérique bloc compressé en RAM utilisé comme swap prioritaire, et systemd-oomd, un démon en espace utilisateur qui observe la pression mémoire (PSI) des cgroups v2 et tue un cgroup descendant avant que l'hôte ne se fige.

Le prérequis rappelé par l'article mérite d'être répété : le swap n'est pas de la RAM de secours. Il existe pour que des pages anonymes rarement utilisées puissent être récupérées comme le sont les pages de fichiers. Sans swap du tout, ces pages restent épinglées et c'est le cache qui trinque.

Comment s'y prendre

Le swap compressé. zram-generator est un générateur d'unités systemd : on dépose un fichier, il crée et active le périphérique au démarrage.

INI
# /etc/systemd/zram-generator.conf
[zram0]
zram-size = min(ram / 2, 8192)   # capacité non compressée ; défaut : min(ram/2, 4096)
compression-algorithm = zstd
swap-priority = 100
options = discard

Le rapport de compression attendu est de l'ordre de 2:1, variable selon la charge. zram-resident-limit pose un plafond sur la RAM réellement occupée après compression — utile sur une machine de 1 à 2 Go.

Le piège à vérifier en premier : si zswap est actif — c'est le cas par défaut sur beaucoup de noyaux —, il s'intercale devant les périphériques de swap et intercepte les pages avant qu'elles n'atteignent zram. On choisit l'un ou l'autre :

Terminal
cat /sys/module/zswap/parameters/enabled
echo 0 | sudo tee /sys/module/zswap/parameters/enabled   # puis zswap.enabled=0 au boot

Les sysctls. Ils paraissent aberrants pour du swap sur disque, et sont cohérents pour du swap en mémoire : la documentation du noyau admet des valeurs au-delà de 100 quand le swap est rapide.

INI
# /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

page-cluster = 0 coupe la lecture anticipée du swap : zram n'a aucune localité de disque à amortir.

Le démon. systemd-oomd fonctionne par opt-in, unité par unité. La politique conseillée place la surveillance du swap haut dans l'arbre, et celle de la pression sur les tranches inférieures, avec un seuil plus strict pour les sessions interactives :

INI
# /etc/systemd/system/-.slice.d/20-oomd-swap.conf
[Slice]
ManagedOOMSwap=kill

# /etc/systemd/system/user.slice.d/20-oomd-pressure.conf
[Slice]
ManagedOOMMemoryPressure=kill
ManagedOOMMemoryPressureLimit=40%

Sur system.slice, la même directive avec 60 %. Les valeurs par défaut globales, elles, sont SwapUsedLimit=90%, DefaultMemoryPressureLimit=60% et DefaultMemoryPressureDurationSec=30s.

Un réglage à ne pas oublier : protéger ce par quoi vous reprenez la main.

INI
# drop-in sur ssh.service
[Service]
ManagedOOMPreference=avoid

Vérifier

zramctl donne les quatre colonnes qui comptent — DISKSIZE (capacité configurée), DATA (octets non compressés stockés), COMPR (charge utile compressée) et TOTAL (RAM réellement consommée, surcoût d'allocateur inclus). oomctl dump montre les cgroups surveillés, et /proc/pressure/memory distingue some (des tâches attendent) de full (tout le monde attend — c'est le thrashing).

Le test de charge se fait sur une machine jetable, dans un scope éphémère (systemd-run --scope -p MemoryMax=512M … stress-ng), jamais sur un hôte de production.

Source : DEV Community, Stop Thrashing Under Memory Pressure: Practical zram + systemd-oomd on Linux