Optimisation du débit réseau Linux en réglant les paramètres sysctl TCP/IP
Réglages pratiques des sysctl TCP sous Linux pour le débit, les tampons, le contrôle de congestion et les tests sécurisés.
Optimisation du débit réseau Linux en réglant les paramètres sysctl TCP/IP
L'optimisation du débit réseau Linux commence par une question ennuyeuse : qu'est-ce qui est réellement lent ? Un serveur qui plafonne à 300 Mbps sur une liaison 10 Gbps peut avoir un problème de fenêtre TCP, un problème de disque, un problème d'interruption CPU, un mauvais paramétrage de carte réseau virtuelle, un problème de perte de paquets, ou une application qui envoie des données en petits morceaux. Le réglage des sysctl n'aide que pour certains de ces problèmes.
C'est pourquoi je traite les modifications des sysctl TCP/IP comme des expériences contrôlées, et non comme des recettes magiques de performance. Commencez par une base de référence, modifiez un petit groupe de paramètres, testez à nouveau, et prenez des notes. Si vous copiez un bloc de réglage géant depuis Internet dans /etc/sysctl.conf, vous pouvez améliorer une charge de travail et en pénaliser silencieusement une autre.
Les paramètres ci-dessous sont utiles lorsque vous exécutez des services à haut débit : dépôts d'artefacts, serveurs de sauvegarde, passerelles de stockage objet, proxys inverses très sollicités, réplicas de base de données transférant de gros journaux, ou hôtes Linux déplaçant du trafic sur des liaisons longue distance. Ils sont moins susceptibles d'aider si votre goulot d'étranglement est le CPU de chiffrement TLS, le stockage lent, le verrouillage d'application, les limites du fournisseur cloud, ou les pertes de paquets en dehors de l'hôte.
Avant de changer quoi que ce soit, collectez une base de référence rapide :
ip -s link
ss -s
nstat -az | egrep 'TcpRetransSegs|TcpExtTCPLoss|TcpExtTCPTimeouts|TcpExtListenOverflows'
sar -n DEV,TCP,ETCP 1 10
iperf3 -c test-host -P 4 -t 30
Si vous voyez les retransmissions augmenter, corrigez les pertes avant d'augmenter les tampons. Si le CPU est déjà saturé dans top, mpstat, ou perf, les sysctls peuvent masquer le symptôme mais pas supprimer le goulot d'étranglement. Si iperf3 est rapide mais votre application est lente, examinez le chemin de l'application avant de régler le noyau.
Comment sysctl s'intègre dans l'optimisation réseau
sysctl expose les paramètres du noyau pendant que le système fonctionne. Les paramètres réseau se trouvent généralement sous net.ipv4, net.ipv6, et net.core. Vous pouvez lire une valeur comme ceci :
sysctl net.ipv4.tcp_congestion_control
sysctl net.ipv4.tcp_rmem
sysctl net.core.rmem_max
Vous pouvez tester un changement temporaire comme ceci :
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
Les changements temporaires disparaissent après un redémarrage. Les changements persistants doivent être placés dans un fichier dédié tel que /etc/sysctl.d/90-network-throughput.conf, et non dispersés dans /etc/sysctl.conf sans explication.
sudo install -m 0644 /dev/null /etc/sysctl.d/90-network-throughput.conf
sudo editor /etc/sysctl.d/90-network-throughput.conf
sudo sysctl --system
Utilisez un fichier séparé car l'annulation est simple : déplacez le fichier et exécutez à nouveau sudo sysctl --system. Cela est important lorsqu'un paramètre se comporte mal sous le trafic de production.
Tampons TCP : Donnez de l'espace aux longues connexions
Le premier endroit où les gens regardent est le dimensionnement des tampons. TCP a besoin de suffisamment d'espace de fenêtre d'envoi et de réception pour maintenir les données en vol pendant que les accusés de réception traversent le réseau. Le modèle mental utile est le produit bande passante-délai : une connexion à haute bande passante et haute latence a besoin de plus de données en vol qu'une connexion LAN à faible latence.
Par exemple, un transfert de 1 Gbps sur un chemin de centre de données de 1 ms a besoin de beaucoup moins de données en vol qu'un transfert de 1 Gbps sur un chemin WAN de 70 ms. Si la fenêtre de réception est trop petite, l'émetteur s'arrête même si la liaison a de la place.
Linux utilise des tableaux à trois valeurs pour le réglage de la mémoire TCP :
net.ipv4.tcp_rmem = 4096 131072 33554432
net.ipv4.tcp_wmem = 4096 131072 33554432
Les trois nombres sont les tailles de tampon par socket minimales, par défaut et maximales en octets. Les valeurs exactes doivent correspondre à votre charge de travail, votre budget mémoire et le comportement du noyau. L'exemple ci-dessus augmente le maximum à 32 Mio, ce qui est souvent suffisant pour les serveurs occupés sans être imprudent. Certains systèmes longue distance ou à stockage intensif utilisent des valeurs plus grandes, mais cela doit être testé avec du trafic réel.
Les limites net.core plafonnent les tampons de socket :
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
Si tcp_rmem indique que TCP peut atteindre 32 Mio mais que net.core.rmem_max est beaucoup plus bas, le plafond le plus bas l'emporte en pratique. Gardez les plafonds alignés avec les maximums TCP sauf si vous avez une raison de ne pas le faire.
N'augmentez pas les tampons aveuglément sur une machine avec de nombreuses connexions simultanées. Un serveur de fichiers avec quelques gros flux peut se permettre des tampons par flux plus grands. Un proxy gérant des centaines de milliers de connexions peut brûler de la mémoire rapidement si vous rendez chaque socket éligible à d'énormes tampons.
L'auto-réglage fait déjà une partie du travail
Les noyaux Linux modernes auto-règlent déjà les tampons TCP. Cela signifie que vous n'avez généralement pas besoin de définir d'énormes tampons de socket fixes dans l'application. Le noyau augmente les tampons lorsqu'une connexion bénéficie de plus d'espace.
Votre travail consiste principalement à vous assurer que le plafond n'est pas trop bas. Si le débit est médiocre sur un réseau long et large et que ss -tin montre de petites fenêtres de réception ou un émetteur bloqué par le récepteur, augmenter tcp_rmem, tcp_wmem, rmem_max et wmem_max peut aider.
Vérifiez les connexions actives avec :
ss -tin dst <ip-pair>
Recherchez des champs tels que cwnd, rtt, rto, bytes_acked, bytes_received et les compteurs de retransmission. Ils racontent une meilleure histoire qu'un seul test de vitesse.
Contrôle de congestion : CUBIC, BBR et réalité
L'algorithme de contrôle de congestion décide comment TCP augmente ou réduit son débit d'envoi. Sur de nombreux systèmes Linux, CUBIC est la valeur par défaut et fonctionne bien pour le trafic Internet général et les centres de données. BBR peut améliorer le débit et la latence sur certains chemins avec pertes ou longue distance car il modélise la bande passante du goulot d'étranglement et le temps d'aller-retour au lieu de réagir uniquement à la perte de paquets.
Vérifiez les algorithmes disponibles :
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control
Activez BBR uniquement si votre noyau le propose :
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
Pour la persistance :
net.ipv4.tcp_congestion_control = bbr
Certains systèmes nécessitent également le planificateur de files d'attente équitables pour un bon comportement BBR :
net.core.default_qdisc = fq
Ne supposez pas que BBR est toujours plus rapide. Il peut modifier l'équité avec d'autres flux, et différentes versions de BBR se comportent différemment selon les noyaux. Testez-le sur le même modèle de trafic qui vous intéresse : de nombreux petits appels API, quelques transferts en masse, du trafic de base de données répliqué, ou une charge mixte proche de la production.
Files d'attente d'écoute : Corrigez les pertes avant qu'elles ne deviennent des mystères
Les problèmes de débit se manifestent parfois par des échecs de connexion lors des pics de trafic. Si un service accepte les nouvelles connexions TCP plus lentement que les clients ne les créent, les files d'attente du noyau se remplissent.
Paramètres pertinents :
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
somaxconn plafonne le backlog de connexions terminées demandé par les applications via listen(2). tcp_max_syn_backlog affecte la capacité de la file d'attente SYN semi-ouverte. Les augmenter peut aider les serveurs web, proxys et équilibreurs de charge occupés, mais l'application doit également demander un backlog suffisamment grand. Nginx, HAProxy, Envoy et les serveurs d'applications ont souvent leurs propres paramètres de backlog.
Surveillez les débordements :
nstat -az | egrep 'ListenOverflows|ListenDrops|Syncookies'
ss -ltn
Si ListenOverflows augmente, les files d'attente du noyau ne suivent pas. Si le CPU est saturé ou l'application bloquée sur des services en aval, augmenter les tailles de file d'attente peut réduire brièvement les erreurs client mais ne résoudra pas le service.
Backlog et traitement des paquets
net.core.netdev_max_backlog contrôle combien de paquets peuvent attendre dans la file d'attente d'entrée lorsque le noyau reçoit des paquets plus rapidement qu'il ne peut les traiter.
net.core.netdev_max_backlog = 250000
Cela peut aider sur les interfaces à haute vitesse pendant les rafales, surtout avec la virtualisation réseau. Cela peut également ajouter de la latence si vous transformez l'hôte en une grande salle d'attente de paquets. Vérifiez d'abord les pertes d'interface :
ip -s link show dev eth0
ethtool -S eth0 | egrep 'drop|err|timeout|miss|fifo'
Si les pertes au niveau du pilote augmentent, inspectez également les tailles d'anneau NIC, la distribution des interruptions, les files RSS et l'affinité CPU. Ceux-ci sont en dehors de sysctl, mais ils comptent souvent plus que les tampons TCP sur les hôtes 10 Gbps et plus rapides.
TIME_WAIT et épuisement des ports
Les clients, proxys et exécuteurs de tâches à haut débit peuvent manquer de ports éphémères ou accumuler de nombreux sockets dans TIME_WAIT. Soyez prudent ici car les anciens conseils de réglage peuvent être nocifs.
Vérifiez la plage actuelle :
sysctl net.ipv4.ip_local_port_range
ss -tan state time-wait | wc -l
Un ajustement raisonnable côté client consiste à élargir la plage de ports éphémères :
net.ipv4.ip_local_port_range = 10240 60999
Évitez les anciens conseils qui recommandent tcp_tw_recycle ; il a été supprimé de Linux car il cassait le trafic valide, en particulier derrière du NAT. tcp_tw_reuse existe sur de nombreux noyaux, mais son comportement a changé au fil du temps. Ne l'activez pas comme paramètre de débit par défaut. Si vous pensez en avoir besoin, testez votre noyau et votre modèle de trafic exacts avec soin.
Pour les serveurs, un tas de sockets TIME_WAIT est souvent normal. Pour les clients, l'épuisement des ports signifie généralement que vous avez besoin de pooling de connexions, de keep-alive, de HTTP/2, de moins de connexions sortantes de courte durée, ou de plus d'IP sources.
Un fichier de départ conservateur
Voici un point de départ pratique pour un serveur à haut débit. Il n'est intentionnellement pas extrême :
# /etc/sysctl.d/90-network-throughput.conf
# Plafonds d'auto-réglage TCP plus grands pour les chemins à haute bande passante ou latence plus élevée.
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
net.ipv4.tcp_rmem = 4096 131072 33554432
net.ipv4.tcp_wmem = 4096 131072 33554432
# Files d'attente plus grandes pour le trafic entrant en rafales.
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
net.core.netdev_max_backlog = 250000
# Optionnel : testez avant d'activer globalement.
# net.core.default_qdisc = fq
# net.ipv4.tcp_congestion_control = bbr
Appliquez-le :
sudo sysctl --system
Puis mesurez à nouveau. Utilisez la même taille de test, la même fenêtre de temps, le même nombre de flux parallèles et le même chemin réseau. Un test avant-après qui modifie cinq variables n'est pas une preuve.
Erreurs courantes
La première erreur est de régler sur un chemin avec pertes. TCP considère la perte comme de la congestion. Des tampons plus grands peuvent augmenter un peu le débit, mais ils peuvent aussi augmenter la latence et cacher le vrai problème. Corrigez d'abord les mauvais câbles, les commutateurs virtuels surchargés, le filtrage de paquets, les discordances MTU et les chemins VPN instables.
La deuxième erreur est de supposer que iperf3 -P 8 prouve la performance de l'application. Les flux parallèles peuvent remplir une liaison même lorsqu'une seule connexion d'application réelle ne le peut pas. C'est une information utile, mais ce n'est pas toute l'histoire.
La troisième erreur est de définir d'énormes tampons sur des hôtes partagés. Des plafonds plus grands sont acceptables lorsque le noyau augmente les tampons uniquement en cas de besoin, mais la pression mémoire change tout. Surveillez free, slabtop, la mémoire TCP et la mémoire de l'application après les changements.
La quatrième erreur est d'oublier l'annulation. Conservez les valeurs précédentes dans votre ticket de modification ou votre runbook :
sysctl -a | egrep 'net.core.rmem_max|net.core.wmem_max|net.ipv4.tcp_rmem|net.ipv4.tcp_wmem|net.ipv4.tcp_congestion_control'
Quand sysctl n'est pas la solution
Si un cœur CPU est saturé tandis que les autres sont inactifs, examinez la gestion des interruptions, RSS, RPS/XPS et le threading de l'application. Si l'attente disque est élevée, le réseau peut attendre le stockage. Si TLS consomme du CPU, testez avec et sans chiffrement et envisagez le matériel, le choix de chiffrement ou la réutilisation de connexion. Si Kubernetes ou un équilibreur de charge cloud se trouve sur le chemin, vérifiez les limites au niveau du service et les tables conntrack.
Pour les hôtes avec beaucoup de NAT, inspectez également conntrack :
sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max
Ce n'est pas du réglage de débit TCP, mais l'épuisement de conntrack peut ressembler à un ralentissement réseau aléatoire ou à des connexions interrompues.
Tester sans se tromper soi-même
Utilisez iperf3 comme outil réseau, pas comme preuve que l'application est corrigée. Un test à flux unique est utile car il montre ce qu'une seule connexion TCP peut faire :
iperf3 -c test-host -t 30
Un test parallèle montre si la liaison peut être remplie par plusieurs flux :
iperf3 -c test-host -P 8 -t 30
Si les flux parallèles sont rapides mais qu'un seul flux est lent, examinez le contrôle de congestion, la croissance de la fenêtre TCP, le RTT et la perte de paquets. Si les deux sont lents, regardez plus bas : erreurs d'interface, limites de bande passante cloud, saturation CPU, MTU, inspection du pare-feu, ou stockage derrière l'émetteur et le récepteur.
Gardez le chemin de test réaliste. Tester deux hôtes dans le même rack ne vous en dira pas long sur un travail de sauvegarde traversant des régions. Tester avec un petit fichier n'exposera pas le débit en régime permanent. Tester via un VPN peut mesurer l'appliance VPN plus que le TCP Linux.
Après chaque changement, capturez les mêmes compteurs :
nstat -az > /tmp/nstat-after.txt
ss -s
sar -n DEV,TCP,ETCP 1 10
Le résultat utile n'est pas seulement "le nombre a augmenté". Vous voulez savoir si les retransmissions ont diminué, si les files d'attente ont cessé de déborder, si le CPU est resté raisonnable et si la latence ne s'est pas aggravée pour les petites requêtes.
Un bon réglage réseau Linux est mesuré et réversible. Augmentez les plafonds des tampons TCP lorsque le chemin a besoin de fenêtres plus grandes. Testez le contrôle de congestion au lieu de supposer qu'un algorithme gagne partout. Augmentez les files d'attente d'écoute lorsque vous voyez des pertes de file d'attente, et corrigez l'application si elle ne peut pas accepter assez rapidement. sysctl est utile, mais c'est une couche dans un système plus vaste.