Aller au contenu

Swap

Quelle taille de swap mettre en place pour un serveur sous Linux

C’est une question récurrente. Une réponse «historique» pour les systèmes d’exploitation Unix est de mettre en place un swap d’une taille égale au double de la RAM.

Ce paramétrage n’est plus du tout d’actualité de nos jours, et est même très souvent contre-productif.

Voir cet article (en anglais) pour une compréhension plus détaillée et précise de ce qui est écrit sur cette page : https://chrisdown.name/2018/01/02/in-defence-of-swap.html

Les raisons historiques

Cette règle date des premiers systèmes V Unix et des premiers BSD. À l’époque, chaque octet alloué de la RAM devait avoir un pendant dans le swap, même s’il n’était pas swappé, afin de garder des algorithmes de gestion de la RAM assez simples. On avait donc comme règle de mettre 2 fois la quantité de mémoire en swap, afin d’avoir réellement 2 fois la mémoire réelle d’utilisable. Les algorithmes de l’époque avaient tendance à mal se comporter si on ne respectait pas cette règle (principalement des erreurs d’allocation mémoire alors que de la mémoire était encore disponible). Cela date de l’époque de SunOS par exemple (pas Solaris, c’est donc quelque chose d’assez vieux).

Une autre raison était qu’en cas de crash du système d’exploitation, on vidait toute la mémoire du système dans le swap pour analyse. Il fallait donc qu’il soit plus grand que la mémoire du système.

Pourquoi cette règle ne doit surtout plus être appliquée ?

À l’époque (il y a une vingtaine d’années), le temps d’accès au disque était de l’ordre de 10 à 20ms (pour les plus performants). Les processeurs étaient au mieux à une centaine de MHz, et la RAM avait de faibles performances, largement suffisantes pour ces processeurs. De plus, la mémoire coûtait très cher. Depuis, la loi de Moore a fait son effet, et les processeurs sont devenus extrêmement rapides. La RAM n’a pas suivi un accroissement aussi rapide, mais tout de même bien plus rapide que les temps d’accès disque. La RAM est donc proportionnellement bien plus rapide que le disque (8ns pour la RAM, 5 ms pour le disque), et est devenue bien moins chère, même en grande quantité.

Nous avons donc d’un côté une RAM devenue vraiment rapide (X100) et abondante (X1000, X10000 ?, 1 To de Ram n’est plus inenvisageable ), et de l’autre un disque dur qui n’a fait que X10 en étant optimiste depuis l’époque (en vitesse d’accès aléatoire). L’accès au swap pour des données utiles est donc devenu assez prohibitif en termes de coûts. Cependant, il est toujours intéressant d’avoir un peu de swap pour pouvoir y déposer ce qui est chargé par les programmes mais ne sert à rien en temps normal (un démon dont on n’a besoin qu’une fois par jour, par exemple, ou pour pallier une fuite mémoire…), mais certainement plus dans une optique d’«étendre» la RAM.

Si nous imaginons un système avec une forte quantité de RAM, un gros swap (la règle du X2 par exemple, 64Go de RAM, 128Go de swap), que se passe-t-il quand il est à court de mémoire (en très simplifié bien sûr) ? Le système va commencer à remplir le swap. Quand le swap sera plein (on imagine une application qui a vraiment un bug comme un algorithme qui part en boucle, alloue de la mémoire en permanence et l’utilise), il essayera encore de gagner de la place en réduisant le cache, ce qui diminuera encore l’efficacité de l’ensemble du système, jusqu’à ce que le swap soit plein, le système n’ait plus de cache, et on se retrouve dans ce qu’on appelle un swap storm: toutes les applications actives veulent travailler, font donc des défauts de page pour demander de récupérer des données provenant du swap, ce qui réenvoie en swap d’autres pages appartenant à d’autres programmes. Bref, la RAM n’est plus vraiment utilisée, c’est le temps d’accès du swap qui prime sur tout le reste. Habituellement un système dans cet état n’est plus utilisable, et doit être redémarré électriquement. Le gros swap est donc plus contre-productif qu’autre chose, de nos jours: le gain de mémoire obtenu par le swap est sans intérêt par rapport au risque d’effondrement encouru si le système est à court de mémoire.

Combien mettre de swap ?

Au dessus de 2 Go, il ne servira à rien. Il est très peu probable, sur un système moderne, qu’un swap de 2 Go soit rempli. Et si c’est le cas, c’est qu’une application a une fuite mémoire, donc avoir plus de swap ne servira qu’à repousser un peu sa mort, en prenant le risque de déstabiliser tout le système.

Si vous avez un système qui n’est pas dédié à PostgreSQL, vous pouvez revoir cette valeur un peu à la hausse, certaines applications comme Java ayant tendance à sur-allouer de la mémoire sans l’utiliser.

Par ailleurs, si vous recherchez des préconisations «constructeur», voici ce qu’on peut trouver dans la littérature:

Commandes

Pour voir le swap en place :

swapon -s
LANG=C free -m
LANG=C swapon -s

Pour l’utilisation :

vmstat 1
Pour régler la propension à swapper (« swappiness ») :

  • voir la page Options kernel sur Linux pour PostgreSQL pour modifier vm.swappiness
  • voir la page overcommit pour le réglage de l’overcommit qui fera tomber une requête gourmande en erreur pour éviter à tout prix de swapper.

Pour voir ce qui peut occuper un swap bizarrement plein alors qu’il est presque désactivé :

  • un script :

    for pid in /proc/*/status ; do awk '/^(Name|Pid|VmSwap)/ {printf $2" "$3}END{print ""}' ${pid}; done | grep kB | grep -wv "0 kB"
    

  • un outil :

    smem -s swap -r
    

  • le contenu des tmpfs :

    df -hT |grep tmpfs
    

  • l’emplacement et la taille des journaux de systemd :

    journalctl --disk-usage
    
    du -smxh /var/log/journal
    du -smxh /run/log/journal
    
    journaux que l’on peut au besoin purger selon l’âge ou la volumétrie :
    journalctl --vacuum-time=2d
    journalctl --vacuum-size=500M