Performance réseau (sysctl)
| Fiche express | |
|---|---|
| Domaine | Tuning réseau (buffers TCP, files d'attente, congestion) |
| Commande | sysctl, /etc/sysctl.d/*.conf
|
| Contexte | Linux — serveurs à fort trafic ou forte concurrence de connexions |
| Voir aussi | Ss (état des connexions en direct) |
Réglages sysctl pour améliorer le débit et la tenue en charge réseau d'un serveur Linux : tailles de buffers, files d'attente de connexions, contrôle de congestion TCP. Utile en cas de débit décevant sur un lien rapide, de connexions rejetées sous forte charge, ou de latence anormale.
Appliquer les réglages
Un réglage posé avec sysctl -w est immédiat mais ne survit pas à un redémarrage : le persister passe par un fichier dans /etc/sysctl.d/.
sysctl net.ipv4.tcp_congestion_control # lire une valeur courante
sysctl -w net.core.somaxconn=4096 # appliquer à chaud (perdu au reboot)
echo "net.core.somaxconn = 4096" >> /etc/sysctl.d/99-network-tuning.conf
sysctl --system # recharge tous les fichiers sysctl.d (persistant)
Buffers TCP (rmem/wmem)
Augmenter les tailles de buffer socket profite surtout aux liens à fort débit et forte latence (BDP élevé — longue distance, gros pipe) ; sur un LAN ou un lien à faible latence l'effet est marginal.
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216 # min / défaut / max, buffer de réception
net.ipv4.tcp_wmem = 4096 65536 16777216 # min / défaut / max, buffer d'émission
Contrôle de congestion (BBR)
BBR (Google) donne en général un meilleur débit que l'algorithme historique cubic sur les liens avec pertes de paquets ou forte latence. Il requiert le qdisc fq pour fonctionner correctement.
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
modprobe tcp_bbr # si le module n'est pas déjà chargé
sysctl net.ipv4.tcp_available_congestion_control # liste les algorithmes disponibles
Files d'attente de connexions
À revoir à la hausse sur un serveur qui encaisse beaucoup de connexions entrantes simultanées (reverse proxy, serveur web très sollicité) ; une file trop courte se traduit par des connexions refusées ou des SYN silencieusement droppés en pic de charge.
net.core.somaxconn = 4096 # backlog max d'écoute (queue accept())
net.ipv4.tcp_max_syn_backlog = 8192 # backlog des connexions à moitié ouvertes (SYN_RECV)
net.core.netdev_max_backlog = 5000 # file d'attente des paquets avant traitement par le protocole
net.ipv4.tcp_syncookies = 1 # protection contre le SYN flood (activé par défaut)
Réutilisation des sockets en TIME_WAIT
Un serveur qui ouvre beaucoup de connexions sortantes courtes (proxy, appels API) peut épuiser sa plage de ports locaux avec des sockets en TIME_WAIT.
net.ipv4.tcp_tw_reuse = 1 # réutilise les sockets TIME_WAIT pour de nouvelles connexions sortantes
net.ipv4.ip_local_port_range = 1024 65535 # plage de ports éphémères disponibles
net.ipv4.tcp_fin_timeout = 15 # délai avant libération d'une socket FIN_WAIT2 (défaut 60)
⚠️ Ne pas activer net.ipv4.tcp_tw_recycle : supprimé depuis le noyau 4.12, et sur les versions plus anciennes il casse les connexions entrantes derrière un NAT partagé (plusieurs clients derrière la même IP publique se font rejeter). tcp_tw_reuse seul est sûr et suffisant.
Keepalive TCP
Utile pour détecter plus vite une connexion morte (client déconnecté sans fermeture propre, coupure réseau) sans attendre le timeout applicatif.
net.ipv4.tcp_keepalive_time = 300 # délai avant la première sonde keepalive (défaut 7200s, trop long)
net.ipv4.tcp_keepalive_intvl = 30 # intervalle entre sondes
net.ipv4.tcp_keepalive_probes = 5 # nombre de sondes avant de considérer la connexion morte
Surveiller le débit d'une interface en temps réel
Petit script pour visualiser rapidement l'effet d'un réglage : il affiche le débit entrant/sortant d'une interface en le calculant à partir des compteurs bruts exposés par le noyau dans /sys/class/net/.
#!/bin/bash
IF=$1
if [ -z "$IF" ]; then
echo "usage: $0 <interface> (ex: $0 eth0)"
exit 1
fi
while true; do
R1=$(cat /sys/class/net/$IF/statistics/rx_bytes)
T1=$(cat /sys/class/net/$IF/statistics/tx_bytes)
sleep 1
R2=$(cat /sys/class/net/$IF/statistics/rx_bytes)
T2=$(cat /sys/class/net/$IF/statistics/tx_bytes)
echo "rx $IF: $(( (R2 - R1) / 1024 )) kB/s tx $IF: $(( (T2 - T1) / 1024 )) kB/s"
done