Swap sous Linux : Comprendre swappiness=0 vs swappiness=1 selon les distributions
La configuration du swap et du paramètre vm.swappiness est l'une des optimisations les plus controversées sous Linux. Selon votre distribution et version du kernel, swappiness=0 peut avoir des comportements radicalement différents. Voici un guide complet pour naviguer ces subtilités.
Le mythe de swappiness=0
Comportement historique vs moderne
Avant kernel 3.5 :
swappiness=0= swap complètement désactivé- Risque d'OOM (Out of Memory) même avec du swap disponible
Kernel 3.5+ :
swappiness=0= swap seulement en cas de pression mémoire critique- Plus sûr mais encore agressif
Kernel 4.0+ :
swappiness=1recommandé pour éviter le swapswappiness=0peut causer des OOM inattendus
Comportements par distribution
Ubuntu (16.04+)
Configuration par défaut :
# Ubuntu 16.04-20.04
cat /proc/sys/vm/swappiness
# 60 (défaut conservateur)
# Ubuntu 22.04+
cat /proc/sys/vm/swappiness
# 60 (inchangé)
Recommandations Ubuntu :
# Pour serveurs de production
vm.swappiness = 1
# Pour desktops avec SSD
vm.swappiness = 10
# Pour serveurs bases de données
vm.swappiness = 1
vm.vfs_cache_pressure = 50
Particularités Ubuntu :
- Support excellent du
swappiness=1depuis 18.04 - Zswap activé par défaut sur les versions récentes
- Swap file par défaut au lieu de partition
Red Hat Enterprise Linux (RHEL 7/8/9)
RHEL 7 (kernel 3.10) :
# Comportement legacy - attention !
cat /proc/sys/vm/swappiness
# 30 (défaut RHEL)
# Configuration recommandée RHEL 7
vm.swappiness = 10 # PAS 0 ou 1 sur RHEL 7 !
vm.dirty_ratio = 40
vm.dirty_background_ratio = 10
RHEL 8/9 (kernel 4.18+) :
# Kernel moderne - swappiness=1 OK
vm.swappiness = 1
# Avec tuned pour optimisation automatique
tuned-adm profile throughput-performance
# OU
tuned-adm profile latency-performance
Particularités Red Hat :
tuneddaemon peut overrider vos paramètres- RHEL 7 : éviter
swappiness=0(OOM garantis) - RHEL 8+ :
swappiness=1sûr et recommandé
Fedora (33+)
Configuration moderne :
# Fedora utilise systemd-oomd par défaut
systemctl status systemd-oomd
# Active par défaut depuis Fedora 34
# Configuration recommandée
vm.swappiness = 1
vm.watermark_boost_factor = 0
vm.watermark_scale_factor = 125
Avec systemd-oomd :
# Configuration /etc/systemd/oomd.conf
[OOM]
SwapUsedLimit=90%
DefaultMemoryPressureLimit=60%
DefaultMemoryPressureDurationSec=20s
Particularités Fedora :
systemd-oomdremplace partiellement le swap traditionnel- Zram swap par défaut sur Fedora Workstation
swappiness=1optimal avec systemd-oomd
CentOS Stream / AlmaLinux / Rocky Linux
Basés sur RHEL - mêmes règles :
# CentOS Stream 8/9, AlmaLinux 8/9, Rocky 8/9
vm.swappiness = 1
# CentOS 7 (legacy)
vm.swappiness = 10
Tests et validation par distribution
Script de test universel :
#!/bin/bash
# test-swappiness.sh - Test comportement swap par distribution
# Détection distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
DISTRO=$ID
VERSION=$VERSION_ID
else
DISTRO="unknown"
fi
KERNEL=$(uname -r | cut -d. -f1-2)
echo "=== Test Swappiness ==="
echo "Distribution: $DISTRO $VERSION"
echo "Kernel: $KERNEL"
echo "Swappiness actuel: $(cat /proc/sys/vm/swappiness)"
echo
# Test mémoire disponible
TOTAL_MEM=$(free -g | awk '/^Mem:/{print $2}')
AVAILABLE_MEM=$(free -g | awk '/^Mem:/{print $7}')
SWAP_TOTAL=$(free -g | awk '/^Swap:/{print $2}')
SWAP_USED=$(free -g | awk '/^Swap:/{print $3}')
echo "Mémoire totale: ${TOTAL_MEM}GB"
echo "Mémoire disponible: ${AVAILABLE_MEM}GB"
echo "Swap total: ${SWAP_TOTAL}GB"
echo "Swap utilisé: ${SWAP_USED}GB"
echo
# Recommandations par distribution
case $DISTRO in
"ubuntu")
if [[ $(echo "$VERSION >= 18.04" | bc -l) -eq 1 ]]; then
echo "Ubuntu $VERSION: swappiness=1 recommandé"
else
echo "Ubuntu $VERSION: swappiness=10 recommandé (version legacy)"
fi
;;
"rhel"|"centos")
if [[ $(echo "$VERSION >= 8" | bc -l) -eq 1 ]]; then
echo "RHEL/CentOS $VERSION: swappiness=1 OK"
else
echo "RHEL/CentOS $VERSION: ÉVITER swappiness=0/1, utiliser 10"
fi
;;
"fedora")
echo "Fedora $VERSION: swappiness=1 + systemd-oomd recommandé"
systemctl is-active systemd-oomd >/dev/null && echo " systemd-oomd: actif" || echo " systemd-oomd: inactif"
;;
*)
echo "Distribution non reconnue, vérifiez la documentation"
;;
esac
# Test de charge mémoire simulé
echo
echo "=== Test simulation charge mémoire ==="
echo "Appuyez sur Enter pour lancer un test de charge mémoire (Ctrl+C pour annuler)"
read
# Consomme de la mémoire progressivement
python3 -c "
import time
data = []
for i in range(100):
try:
# Alloue 100MB par itération
chunk = b'x' * (100 * 1024 * 1024)
data.append(chunk)
print(f'Alloué: {(i+1)*100}MB')
time.sleep(1)
except MemoryError:
print('MemoryError atteint')
break
except KeyboardInterrupt:
print('Test interrompu')
break
"
Configurations optimales par use case
Serveurs de base de données
PostgreSQL :
# /etc/sysctl.d/99-postgresql.conf
vm.swappiness = 1
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
vm.dirty_expire_centisecs = 500
vm.dirty_writeback_centisecs = 250
vm.overcommit_memory = 2
vm.overcommit_ratio = 80
MySQL/MariaDB :
# /etc/sysctl.d/99-mysql.conf
vm.swappiness = 1
vm.dirty_background_ratio = 3
vm.dirty_ratio = 15
# Plus agressif sur les dirty pages pour MySQL
MongoDB :
# /etc/sysctl.d/99-mongodb.conf
vm.swappiness = 1
vm.zone_reclaim_mode = 0
# MongoDB préfère éviter NUMA reclaim
Conteneurs et Kubernetes
Configuration hôte Kubernetes :
# /etc/sysctl.d/99-kubernetes.conf
vm.swappiness = 1
vm.panic_on_oom = 0
vm.overcommit_memory = 1
kernel.panic = 10
kernel.panic_on_oops = 1
# Pour distributions avec systemd-oomd
# Désactiver si problématique avec kubelet
systemctl mask systemd-oomd
Docker en production :
# /etc/sysctl.d/99-docker.conf
vm.swappiness = 1
vm.max_map_count = 262144
# Pour Elasticsearch dans conteneurs
Serveurs web haute charge
Nginx + PHP-FPM :
# /etc/sysctl.d/99-webserver.conf
vm.swappiness = 10 # Légèrement plus tolérant
vm.dirty_background_ratio = 10
vm.dirty_ratio = 20
net.core.somaxconn = 65535
Workstations développeur
Configuration équilibrée :
# /etc/sysctl.d/99-workstation.conf
vm.swappiness = 10
vm.vfs_cache_pressure = 50
vm.dirty_background_ratio = 15
vm.dirty_ratio = 25
Monitoring et troubleshooting
Surveiller l'utilisation swap :
# Script de monitoring continu
#!/bin/bash
# monitor-swap.sh
while true; do
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
SWAP_USED=$(free | awk '/^Swap:/ {printf "%.1f", $3/1024}')
SWAP_TOTAL=$(free | awk '/^Swap:/ {printf "%.1f", $2/1024}')
SWAP_PERCENT=$(free | awk '/^Swap:/ {printf "%.1f", ($3/$2)*100}')
MEM_AVAILABLE=$(free | awk '/^Mem:/ {printf "%.1f", $7/1024}')
if (( $(echo "$SWAP_PERCENT > 1.0" | bc -l) )); then
echo "⚠️ $TIMESTAMP - Swap: ${SWAP_USED}MB/${SWAP_TOTAL}MB (${SWAP_PERCENT}%) - RAM libre: ${MEM_AVAILABLE}MB"
else
echo "✅ $TIMESTAMP - Swap: ${SWAP_USED}MB/${SWAP_TOTAL}MB (${SWAP_PERCENT}%) - RAM libre: ${MEM_AVAILABLE}MB"
fi
sleep 30
done
Analyser les processus swappés :
# Identifier les processus utilisant du swap
for pid in $(ls /proc/*/status 2>/dev/null | cut -d/ -f3); do
swap=$(awk '/^VmSwap:/ {print $2}' /proc/$pid/status 2>/dev/null)
if [[ $swap && $swap -gt 0 ]]; then
comm=$(cat /proc/$pid/comm 2>/dev/null)
echo "PID $pid ($comm): ${swap}kB swap"
fi
done | sort -k3 -nr | head -10
Forcer le retour du swap en RAM :
# Attention : peut causer de la latence !
# Seulement si assez de RAM disponible
if [[ $(free | awk '/^Mem:/ {print $7}') -gt $(free | awk '/^Swap:/ {print $3}') ]]; then
echo "Retour du swap en RAM..."
swapoff -a && swapon -a
echo "Terminé"
else
echo "❌ Pas assez de RAM disponible pour vider le swap"
fi
Dépannage par distribution
Ubuntu : problèmes courants
# Vérifier si snapd utilise trop de swap
systemctl status snapd
snap list
# Désactiver snapd si problématique
systemctl mask snapd
# Ubuntu avec zswap - vérifier config
cat /sys/module/zswap/parameters/enabled
# true
# Ajuster zswap si nécessaire
echo 20 > /sys/module/zswap/parameters/max_pool_percent
RHEL/CentOS : gestion avec tuned
# Voir profil tuned actif
tuned-adm active
# Créer profil personnalisé
mkdir /etc/tuned/custom-lowswap
cat > /etc/tuned/custom-lowswap/tuned.conf << 'EOF'
[main]
summary=Custom profile with minimal swap usage
[sysctl]
vm.swappiness=1
vm.dirty_background_ratio=5
vm.dirty_ratio=10
[vm]
transparent_hugepages=never
EOF
# Activer le profil
tuned-adm profile custom-lowswap
Fedora : systemd-oomd vs swap
# Vérifier configuration systemd-oomd
systemctl status systemd-oomd
journalctl -u systemd-oomd -f
# Ajuster les seuils si nécessaire
cat > /etc/systemd/oomd.conf << 'EOF'
[OOM]
SwapUsedLimit=95%
DefaultMemoryPressureLimit=80%
DefaultMemoryPressureDurationSec=30s
EOF
systemctl restart systemd-oomd
Checklist de migration swappiness
✅ Avant changement en production :
-
Identifier la distribution et version kernel
cat /etc/os-release uname -r -
Tester sur environnement de développement
# Test temporaire echo 1 > /proc/sys/vm/swappiness # Monitorer pendant 24h minimum -
Vérifier la quantité de swap disponible
free -h # Minimum 2GB recommandé même avec swappiness=1 -
Backup configuration actuelle
sysctl -a | grep vm > /root/sysctl-backup-$(date +%Y%m%d).txt
✅ Après changement :
- Monitoring intensif première semaine
- Alertes sur utilisation swap > 10%
- Vérification absence d'OOM dans les logs
- Test de charge pour valider
Conclusion
La configuration optimale du swap dépend étroitement de votre distribution Linux :
Règles universelles :
- Ubuntu 18.04+, RHEL 8+, Fedora 33+ :
swappiness=1sûr et recommandé - RHEL 7, CentOS 7 : éviter
swappiness=0/1, utiliserswappiness=10 - Toutes distributions : maintenir au minimum 2GB de swap même avec
swappiness=1
Points critiques :
- Toujours tester sur un environnement non critique d'abord
- Monitorer l'utilisation mémoire après changement
- Adapter selon le workload (BDD vs web vs conteneurs)
- Tenir compte des outils système (tuned, systemd-oomd, zswap)
La règle d'or : swappiness=1 pour éviter le swap tout en gardant une soupape de sécurité contre les OOM killer inattendus.