Lire « free : 180MB » sur un serveur de 8 Go affole quelqu'un chaque jour, et presque toujours tout va bien. Linux utilise la mémoire disponible comme cache disque et la rend à l'instant où quelque chose en a besoin. Le chiffre à lire est available, pas free.
free -h
# total used free shared buff/cache available
# Mem: 7.8Gi 2.1Gi 180Mi 120Mi 5.5Gi 5.3Gi
5,3 Gi en available veut dire qu'il y a 5,3 Gi à prendre. Le cache n'est pas de la mémoire perdue ; c'est de la mémoire qui fait quelque chose d'utile jusqu'à ce qu'on la réclame.
Le swap est le chiffre qui compte
Que le swap soit OCCUPÉ n'est pas le problème. Qu'on y écrive et qu'on y lise activement, oui : la machine déplace des pages vers le disque pour faire de la place, et le disque est des milliers de fois plus lent que la mémoire. Tout est lent et rien dans l'application ne l'explique.
vmstat 2 5
# watch the si and so columns - sustained non-zero is thrashing
Trouver ce qui la retient
ps aux --sort=-%mem | head -10
smem -rs uss 2>/dev/null | head -10
uss est la mémoire qu'un processus libérerait vraiment s'il se terminait : c'est le chiffre honnête. rss compte deux fois les bibliothèques partagées et fait paraître énorme chaque worker PHP.
La réponse habituelle
- Trop de workers PHP. Un pm.max_children recopié d'un tutoriel au lieu d'être calculé depuis votre RAM. Divisez la mémoire disponible par le worker moyen, et restez prudent.
- Un innodb_buffer_pool_size trop grand. Une base à qui on demande de mettre en cache plus que ce que la machine possède.
- Une fuite dans un worker de longue durée. Redémarrez-le régulièrement ; php-fpm le fait avec pm.max_requests.
Un peu de swap est sain : il permet au noyau d'écarter les pages vraiment inactives. Un serveur sans aucun swap n'a pas de coussin et se fait tuer net dès qu'il manque de mémoire.
