Aller au contenu principal
DEVOPS

Swap sous Linux : Comprendre swappiness=0 vs swappiness=1 selon les distributions

Guide complet de configuration du swap et swappiness selon Ubuntu, RHEL, Fedora avec tests et recommandations par workload.

Florian Courouge
12 min de lecture
👁️1.6k vues
Linux
Swap
Swappiness
Performance
Ubuntu
RHEL
Fedora
Niveau:
Avancé

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.

Linux Memory Management

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=1 recommandé pour éviter le swap
  • swappiness=0 peut causer des OOM inattendus

Swappiness Behavior Evolution

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=1 depuis 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 :

  • tuned daemon peut overrider vos paramètres
  • RHEL 7 : éviter swappiness=0 (OOM garantis)
  • RHEL 8+ : swappiness=1 sûr et recommandé

RHEL Tuned Profiles

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-oomd remplace partiellement le swap traditionnel
  • Zram swap par défaut sur Fedora Workstation
  • swappiness=1 optimal 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

Distribution Comparison

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 :

  1. Identifier la distribution et version kernel

    cat /etc/os-release
    uname -r
    
  2. Tester sur environnement de développement

    # Test temporaire
    echo 1 > /proc/sys/vm/swappiness
    # Monitorer pendant 24h minimum
    
  3. Vérifier la quantité de swap disponible

    free -h
    # Minimum 2GB recommandé même avec swappiness=1
    
  4. Backup configuration actuelle

    sysctl -a | grep vm > /root/sysctl-backup-$(date +%Y%m%d).txt
    

✅ Après changement :

  1. Monitoring intensif première semaine
  2. Alertes sur utilisation swap > 10%
  3. Vérification absence d'OOM dans les logs
  4. 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=1 sûr et recommandé
  • RHEL 7, CentOS 7 : éviter swappiness=0/1, utiliser swappiness=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.