Avancé
⭐ Article vedette

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.

Publié le
10 novembre 2024
Lecture
12 min
Vues
1.6k
Auteur
Florian Courouge
Linux
Swap
Swappiness
Performance
Ubuntu
RHEL
Fedora

Table des matières

📋 Vue d'ensemble rapide des sujets traités dans cet article

Cliquez sur les sections ci-dessous pour naviguer rapidement

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 :

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 :

Points critiques :

La règle d'or : swappiness=1 pour éviter le swap tout en gardant une soupape de sécurité contre les OOM killer inattendus.

À propos de l'auteur

Florian Courouge - Expert DevOps et Apache Kafka avec plus de 5 ans d'expérience dans l'architecture de systèmes distribués et l'automatisation d'infrastructures.

Cet article vous a été utile ?

Découvrez mes autres articles techniques ou contactez-moi pour discuter de vos projets DevOps et Kafka.