Supervision de serveursdébutant7 min de lecture

Lire le load average sur des machines multi-cœurs : les trois malentendus et l'alerte qui fonctionne vraiment

Une charge de 8 est calme sur un 16 cœurs et une catastrophe sur un 2 cœurs. La charge compte aussi les processus qui attendent un disque, pas seulement le CPU. Et la valeur à 1 minute est presque toujours du bruit. Ce que signifient vraiment les trois chiffres, comment les normaliser par cœur, comment séparer la pression CPU de la pression I/O avec /proc/pressure, et quel seuil mettre dans une alerte.

Sommaire
  1. Malentendu 1 : « la charge, c'est l'utilisation CPU »
  2. Malentendu 2 : « une charge au-dessus de 1, c'est mauvais »
  3. Malentendu 3 : « la valeur à 1 minute est la valeur actuelle »
  4. La meilleure source : /proc/pressure (PSI)
  5. L'alerte qui fonctionne vraiment
  6. Que faire quand l'alerte se déclenche ?
  7. Pièges
  8. Ce qu'il vous manque encore
  9. Comment monsys fait
  10. FAQ

load average: 6.12, 5.87, 4.90 — et ensuite ? La plupart des tableaux de bord affichent ces trois chiffres en évidence et la plupart des administrateurs en ont une intuition à peu près juste. « À peu près » est le problème : le load average n'est pas un pourcentage, sur Linux il compte plus que le CPU seul, et sur une machine à 32 cœurs il signifie tout autre chose que sur un VPS à 2 vCPU. Cet article en fait un chiffre interprétable, et une alerte qui ne se déclenche pas chaque nuit à 03:00.

Malentendu 1 : « la charge, c'est l'utilisation CPU »

Le load average est le nombre moyen de processus runnable (qui veulent du CPU, l'ont déjà ou l'attendent) plus, sur Linux, les processus en uninterruptible sleep (état D : en attente d'un disque, de NFS, d'un swap-in). Cette seconde partie est une particularité Linux de 1993 et la source de la plupart des confusions.

cat /proc/loadavg
# 6.12 5.87 4.90 3/1187 481223
#  │    │    │   │  │      └─ dernier PID
#  │    │    │   │  └─ nombre total de threads
#  │    │    │   └─ runnable en ce moment
#  └────┴────┴─ 1, 5, 15 minutes (moyenne amortie exponentiellement)

# Qui contribue ? Threads runnable (R) et uninterruptible (D), maintenant :
ps -eo state,pid,comm | awk '$1=="R"||$1=="D"' | sort | uniq -c | sort -rn | head

Si vous voyez beaucoup de processus D, votre charge est une histoire d'I/O, pas de CPU — et plus de cœurs ne résolvent rien.

Malentendu 2 : « une charge au-dessus de 1, c'est mauvais »

La charge est absolue, pas relative. Sur une machine à N cœurs, une charge de N est le point où chaque cœur a exactement une tâche. Divisez donc toujours par le nombre de cœurs :

nproc                                   # 8
awk -v c="$(nproc)" '{printf "load per core: %.2f %.2f %.2f\n", $1/c, $2/c, $3/c}' /proc/loadavg
# load per core: 0.77 0.73 0.61

Règles empiriques pour le chiffre à 15 minutes par cœur :

Charge par cœur (15 min)Signification
< 0,7De la marge
0,7 – 1,0Pleinement utilisé, pas de file d'attente — bien pour un serveur batch, serré pour un serveur web
1,0 – 2,0File d'attente structurelle : chaque tâche attend en moyenne une autre
> 2,0Surchargé, ou blocage I/O (vérifiez l'état D)

Attention aux conteneurs et VM : nproc dans un conteneur donne le nombre de cœurs de l'hôte, mais votre cgroup n'en a peut-être que deux. cat /sys/fs/cgroup/cpu.max montre le quota (200000 100000 = 2 cœurs).

Malentendu 3 : « la valeur à 1 minute est la valeur actuelle »

Les trois chiffres sont des moyennes amorties exponentiellement. La valeur à 1 minute réagit le plus vite, mais contient donc aussi chaque apt update, chaque logrotate et chaque cron qui a pris tous les cœurs pendant trois secondes. Pour décider, regardez la valeur à 15 minutes ; pour « se passe-t-il quelque chose maintenant », ne regardez pas la charge mais la file d'attente elle-même :

vmstat 1 5
# procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
#  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
#  9  2      0 812344 102212 4211200   0    0   120  3400 2100 5100 71 12  9  8  0  0

r = threads runnable (à comparer à nproc), b = bloqués sur I/O, wa = pourcentage de temps où les CPU attendent l'I/O, st = steal (votre hébergeur vous donne moins de CPU que promis — sur un VPS, la première chose à regarder).

La meilleure source : /proc/pressure (PSI)

Depuis le noyau 4.20, Linux suit par ressource le pourcentage de temps pendant lequel des tâches attendent — CPU, mémoire et I/O séparément. C'est précisément la question à laquelle la charge essaie de répondre, mais sans le mélange.

cat /proc/pressure/cpu
# some avg10=4.21 avg60=3.87 avg300=2.10 total=81234567
cat /proc/pressure/io
# some avg10=18.40 avg60=12.31 avg300=6.02 total=...
# full avg10=9.11  avg60=5.20  avg300=2.40 total=...
cat /proc/pressure/memory

some = pourcentage du temps où au moins une tâche attendait ; full = toutes les tâches attendaient (la machine était à l'arrêt sur cette ressource). Un io full avg60 de 9 % signifie : pendant 9 % de la dernière minute, personne ne faisait rien parce que le disque ne suivait pas. C'est l'alerte que vous voulez — pas « load > 4 ».

PSI est activé par défaut sur Ubuntu 24.04 et Debian 12. Si /proc/pressure manque, psi=1 n'est pas dans la ligne de commande du noyau.

L'alerte qui fonctionne vraiment

Trois règles, par ordre de fiabilité :

  1. cpu some avg300 > 25 — pendant un quart des 5 dernières minutes, quelque chose attendait le CPU. Structurel, pas un pic.
  2. io full avg300 > 5 — la machine était complètement à l'arrêt sur l'I/O 5 % du temps. Disque, NFS ou swap.
  3. load15 / nproc > 2 — la règle filet de sécurité classique, uniquement si PSI n'est pas disponible.
sudo tee /usr/local/sbin/pressure-check.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
NTFY="https://ntfy.example.be/servers"; HOST=$(hostname -s); MSG=()
psi() { awk -v k="$1" -v w="$2" '$1==k { for(i=2;i<=NF;i++) if ($i ~ "^"w"=") { sub(w"=","",$i); print $i } }' "/proc/pressure/$3"; }
if [ -r /proc/pressure/cpu ]; then
  c=$(psi some avg300 cpu); i=$(psi full avg300 io); m=$(psi full avg300 memory)
  awk -v v="$c" 'BEGIN{exit !(v>25)}' && MSG+=("cpu pressure some/5m = ${c}%")
  awk -v v="$i" 'BEGIN{exit !(v>5)}'  && MSG+=("io pressure full/5m = ${i}%")
  awk -v v="$m" 'BEGIN{exit !(v>2)}'  && MSG+=("memory pressure full/5m = ${m}% (swap/OOM proche)")
else
  l=$(awk '{print $3}' /proc/loadavg); c=$(nproc)
  awk -v l="$l" -v c="$c" 'BEGIN{exit !(l/c>2)}' && MSG+=("load15/core = $(awk -v l="$l" -v c="$c" 'BEGIN{printf "%.2f", l/c}')")
fi
# Steal : l'hébergeur ne vous donne pas votre CPU. Colonne cherchée par nom : les procps récents ajoutent "gu" (guest) après "st".
st=$(vmstat 1 2 | awk 'NR==2{for(i=1;i<=NF;i++) if($i=="st") c=i} END{print $c}')
[ "${st:-0}" -gt 10 ] && MSG+=("cpu steal ${st}% — surallocation hébergeur")
[ ${#MSG[@]} -gt 0 ] && printf '%s\n' "${MSG[@]}" | curl -s -H "Title: pressure@$HOST" -H "Priority: high" --data-binary @- "$NTFY" >/dev/null
EOF
sudo chmod 0755 /usr/local/sbin/pressure-check.sh
echo '*/5 * * * * root /usr/local/sbin/pressure-check.sh' | sudo tee /etc/cron.d/pressure-check

Que faire quand l'alerte se déclenche ?

SymptômePremière commandeCause typique
Pression CPU élevée, r > nproctop -o %CPU, pidstat 1Un processus emballé, un cron à la mauvaise heure, une limite de workers trop basse
Pression I/O élevée, beaucoup de Diostat -xz 1, iotop -oSauvegarde, vacuum de base de données, logrotate avec compression, disque plein, disque défaillant
Pression mémoire élevéefree -m, colonnes si/so de vmstatSwap ; une fuite mémoire pas encore tout à fait en OOM
Steal élevérien en localVotre hébergeur. Ticket ou migration.

Pièges

  • Hyperthreading. nproc compte les cœurs logiques. Deux threads sur un cœur physique ne livrent pas 2× le débit ; vous le remarquez déjà au-dessus d'une charge ≈ 0,7 × cœurs physiques. lscpu | grep -E 'Thread|Core'.
  • Conteneurs. /proc/loadavg dans un conteneur est la charge de tout l'hôte. Regardez cpu.stat et cpu.pressure dans le cgroup du conteneur (/sys/fs/cgroup/<chemin>/cpu.pressure).
  • Blocages NFS. Un serveur NFS injoignable met chaque processus touchant le chemin en état D. La charge monte à des centaines pendant que le CPU est inactif. io full dans PSI le voit immédiatement ; l'alerte de charge dit seulement « quelque chose ».
  • Alerter sur la valeur à 1 minute. Chaque logrotate avec gzip produit un pic. Utilisez 5 ou 15 minutes, ou PSI avg300.
  • Seuils fixes sur du matériel variable. « load > 4 » signifie autre chose sur votre VM de dev à 2 cœurs que sur la base de données à 48 cœurs. Normalisez par cœur, ou utilisez PSI, qui est déjà un pourcentage.

Ce qu'il vous manque encore

  • L'historique. « Depuis quand la pression I/O est-elle à 8 % ? » demande une série temporelle ; sar -q donne la charge, mais pas PSI.
  • La normale par heure. Le mardi soir, une charge de 6 est normale (sauvegarde) ; le mardi après-midi, non. Un seuil fixe ne connaît pas la différence.
  • Le lien avec la cause. Pression élevée à 03:00 et la tâche de sauvegarde démarrée à 02:55 : deux logs.

Comment monsys fait

L'agent monsys mesure toutes les 15 secondes la charge, r/b de vmstat, le steal et les trois valeurs PSI, et le hub construit par hôte une baseline par heure de la journée : une règle anomaly_load_avg se déclenche sur l'écart par rapport à ce que cet hôte fait normalement à cette heure, pas sur un chiffre absolu. L'alerte montre les principaux processus et les statistiques I/O du même instant, de sorte que le tableau ci-dessus est déjà rempli avant que vous ne vous connectiez.

FAQ

Qu'est-ce qu'un bon load average ?

Par cœur (charge divisée par nproc) sous 0,7 sur le chiffre à 15 minutes : il y a de la marge. Entre 0,7 et 1, la machine est pleine mais sans file d'attente. Au-dessus de 1, des tâches attendent structurellement — ou il y a un problème d'I/O, que vous vérifiez avec vmstat (colonnes b, wa) ou /proc/pressure/io.

Pourquoi ma charge est-elle élevée alors que le CPU est inactif ?

Parce que Linux compte les processus en uninterruptible sleep (état D, en attente de disque, NFS ou swap). Regardez ps -eo state,comm | grep ^D et /proc/pressure/io. Plus de CPU n'aide pas ici ; un stockage plus rapide ou un correctif pour le montage bloqué, si.

PSI est-il meilleur que le load average ?

Oui, pour l'alerte : il sépare CPU, mémoire et I/O, c'est un pourcentage (pas de normalisation nécessaire) et il mesure le temps d'attente plutôt que le nombre de tâches. Le load average reste utile comme chiffre rapide, mais construisez vos alertes sur /proc/pressure.

Rédigé par l'équipe monsys — des sysadmins qui font cela tous les jours.

Fait à la main ? Laissez monsys s'en charger en continu.

Tout ce que contient ce guide tourne dans monsys comme contrôle permanent, avec historique, alertes et preuves d'audit. 5 serveurs gratuits, hébergés en Belgique, installés en 60 secondes.