52 votes

Windows TCP Window Scaling Atteindre le plateau trop tôt

Scénario : Nous avons un certain nombre de clients Windows qui téléchargent régulièrement de gros fichiers (FTP/SVN/HTTP PUT/SCP) vers des serveurs Linux distants de ~100-160ms. Nous disposons d'une bande passante synchrone de 1Gbit/s au bureau et les serveurs sont soit des instances AWS, soit physiquement hébergés dans des centres de données américains.

Le rapport initial indiquait que les téléchargements vers une nouvelle instance de serveur étaient beaucoup plus lents qu'ils ne pouvaient l'être. Cela s'est confirmé lors des tests et à partir de plusieurs sites ; les clients ont constaté un débit stable de 2 à 5 Mbit/s vers l'hôte à partir de leurs systèmes Windows.

J'ai éclaté iperf -s sur une instance AWS, puis à partir d'une instance Fenêtres client dans le bureau :

iperf -c 1.2.3.4

[  5] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 55185
[  5]  0.0-10.0 sec  6.55 MBytes  5.48 Mbits/sec

iperf -w1M -c 1.2.3.4

[  4] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 55239
[  4]  0.0-18.3 sec   196 MBytes  89.6 Mbits/sec

Ce dernier chiffre peut varier de manière significative lors de tests ultérieurs, (Vagaries of AWS) mais se situe généralement entre 70 et 130Mbit/s, ce qui est plus que suffisant pour nos besoins. En faisant un Wiresharking de la session, je peux voir :

  • iperf -c Windows SYN - Window 64kb, Scale 1 - Linux SYN, ACK : Window 14kb, Scale : 9 (*512) iperf window scaling with default 64kb Window
  • iperf -c -w1M Windows SYN - Windows 64kb, échelle 1 - Linux SYN, ACK : Window 14kb, échelle : 9 iperf window scaling with default 1MB Window

Il est clair que la liaison peut supporter ce débit élevé, mais je dois explicitement définir la taille de la fenêtre pour l'utiliser, ce que la plupart des applications réelles ne me permettent pas de faire. Les poignées de main TCP utilisent les mêmes points de départ dans les deux cas, mais la poignée forcée s'échelonne

Inversement, à partir d'un client Linux sur le même réseau, une ligne droite, iperf -c (en utilisant la valeur par défaut du système, soit 85kb) :

[  5] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 33263
[  5]  0.0-10.8 sec   142 MBytes   110 Mbits/sec

Sans aucun forçage, il évolue comme prévu. Cela ne peut pas être quelque chose dans les sauts intermédiaires ou nos commutateurs/routeurs locaux et semble affecter les clients Windows 7 et 8 de la même manière. J'ai lu beaucoup de guides sur l'auto-tuning, mais il s'agit généralement de désactiver complètement la mise à l'échelle pour contourner un mauvais kit de mise en réseau domestique.

Quelqu'un peut-il me dire ce qui se passe ici et me donner un moyen d'y remédier ? (De préférence quelque chose que je peux coller dans le registre via GPO).

Notes

L'instance AWS Linux en question a les paramètres de noyau suivants appliqués dans sysctl.conf :

net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
net.ipv4.tcp_rmem = 4096 1048576 16777216
net.ipv4.tcp_wmem = 4096 1048576 16777216

J'ai utilisé dd if=/dev/zero | nc redirigeant vers /dev/null au niveau du serveur pour exclure les iperf et de supprimer tout autre goulot d'étranglement éventuel, mais les résultats sont sensiblement les mêmes. Les tests avec ncftp (Cygwin, Native Windows, Linux) se déroulent de la même manière que les tests iperf ci-dessus sur leurs plates-formes respectives.

Editer

J'ai repéré un autre élément cohérent qui pourrait être pertinent : enter image description here

Voici la première seconde de la capture de 1 Mo, avec un zoom avant. On peut y voir Démarrage lent en action lorsque la fenêtre s'agrandit et que la mémoire tampon s'agrandit. Il y a ensuite ce petit plateau de ~0,2s exactement au moment où la fenêtre par défaut iperf test s'aplatit pour toujours. Celui-ci s'étend bien sûr à des hauteurs beaucoup plus vertigineuses, mais il est curieux qu'il y ait une pause dans la mise à l'échelle (les valeurs sont de 1022 octets * 512 = 523264) avant qu'il ne le fasse.

Mise à jour - 30 juin.

Suivi des différentes réponses :

  • Activation de CTCP - Cela ne fait aucune différence ; la mise à l'échelle des fenêtres est identique. (Si je comprends bien, ce paramètre augmente la vitesse à laquelle la fenêtre de congestion est agrandie plutôt que la taille maximale qu'elle peut atteindre).
  • Activation des horodatages TCP. - Pas de changement ici non plus.
  • Algorithme de Nagle - C'est logique et, au moins, cela signifie que je peux probablement ignorer ces points particuliers dans le graphique en tant qu'indication du problème.
  • fichiers pcap : Fichier zip disponible ici : https://www.dropbox.com/s/104qdysmk01lnf6/iperf-pcaps-10s-Win%2BLinux-2014-06-30.zip (Anonymisé avec bittwiste, extrait à ~150MB car il y en a un de chaque client OS pour comparaison)

Mise à jour 2 - 30 juin

O, suite à la suggestion de Kyle, j'ai activé ctcp et désactivé le délestage de cheminée : Paramètres globaux TCP

----------------------------------------------
Receive-Side Scaling State          : enabled
Chimney Offload State               : disabled
NetDMA State                        : enabled
Direct Cache Acess (DCA)            : disabled
Receive Window Auto-Tuning Level    : normal
Add-On Congestion Control Provider  : ctcp
ECN Capability                      : disabled
RFC 1323 Timestamps                 : enabled
Initial RTO                         : 3000
Non Sack Rtt Resiliency             : disabled

Malheureusement, le débit n'a pas changé.

J'ai cependant une question de cause à effet : Les graphiques représentent la valeur RWIN définie dans les ACK du serveur au client. Avec les clients Windows, ai-je raison de penser que Linux ne met pas cette valeur à l'échelle au-delà de ce point bas parce que le CWIN limité du client empêche même ce tampon d'être rempli ? Pourrait-il y avoir une autre raison pour laquelle Linux limite artificiellement le RWIN ?

Note : J'ai essayé d'activer l'ECN pour le plaisir, mais cela n'a rien changé.

Mise à jour 3 - 31 juin.

Aucun changement après la désactivation de l'heuristique et de l'autotuning RWIN. J'ai mis à jour les pilotes réseau Intel à la dernière version (12.10.28.0) avec un logiciel qui expose les réglages de fonctionnalité via les onglets du gestionnaire de périphériques. La carte est une carte réseau embarquée 82579V - (je vais faire d'autres tests avec des clients qui utilisent Realtek ou d'autres fournisseurs).

En me concentrant sur la carte d'interface réseau pour un moment, j'ai essayé ce qui suit (j'ai surtout écarté les coupables improbables) :

  • Augmentation des tampons de réception de 256 à 2k et des tampons d'émission de 512 à 2k (les deux sont actuellement au maximum) - Pas de changement
  • Désactivation de tous les chargements de somme de contrôle IP/TCP/UDP. - Pas de changement.
  • Désactivation de la charge d'envoi importante - Nada.
  • Désactivation de l'IPv6, de la programmation QoS - Rien.

Mise à jour 3 - 3 juillet

En essayant d'éliminer le côté serveur Linux, j'ai démarré une instance de Server 2012R2 et j'ai répété les tests en utilisant iperf (binaire cygwin) et NTttcp .

Avec iperf J'ai dû spécifier explicitement -w1m sur à la fois avant que la connexion n'évolue au-delà de ~5Mbit/s. (Soit dit en passant, j'ai pu vérifier que le BDP de ~5Mbits à 91ms de latence est presque précisément de 64kb. Repérer la limite...)

Les binaires ntttcp présentent désormais une telle limitation. L'utilisation de ntttcpr -m 1,0,1.2.3.5 sur le serveur et ntttcp -s -m 1,0,1.2.3.5 -t 10 sur le client, je constate une nette amélioration du débit :

Copyright Version 5.28
Network activity progressing...

Thread  Time(s) Throughput(KB/s) Avg B / Compl
======  ======= ================ =============
     0    9.990         8155.355     65536.000

#####  Totals:  #####

   Bytes(MEG)    realtime(s) Avg Frame Size Throughput(MB/s)
================ =========== ============== ================
       79.562500      10.001       1442.556            7.955

Throughput(Buffers/s) Cycles/Byte       Buffers
===================== =========== =============
              127.287     308.256      1273.000

DPCs(count/s) Pkts(num/DPC)   Intr(count/s) Pkts(num/intr)
============= ============= =============== ==============
     1868.713         0.785        9336.366          0.157

Packets Sent Packets Received Retransmits Errors Avg. CPU %
============ ================ =========== ====== ==========
       57833            14664           0      0      9.476

Avec 8MB/s, il atteint les niveaux que j'obtenais avec des Windows explicitement grands dans iperf . Curieusement, 80MB dans 1273 buffers = un buffer de 64kB à nouveau. Un autre wireshark montre un bon RWIN variable en provenance du serveur (facteur d'échelle 256) que le client semble respecter ; donc peut-être que ntttcp signale mal la fenêtre d'envoi.

Mise à jour 4 - 3 juillet

À la demande de @karyhead, j'ai effectué quelques tests supplémentaires et généré quelques captures supplémentaires, ici : https://www.dropbox.com/s/dtlvy1vi46x75it/iperf%2Bntttcp%2Bftp-pcaps-2014-07-03.zip

  • Deux de plus iperf tous deux de Windows vers le même serveur Linux qu'auparavant (1.2.3.4) : Une avec une taille de socket de 128k et une fenêtre par défaut de 64k (limite à ~5Mbit/s à nouveau) et une avec une fenêtre d'envoi de 1MB et une taille de socket par défaut de 8kb. (échelles plus élevées)
  • Un ntttcp trace du même client Windows vers une instance EC2 Server 2012R2 (1.2.3.5). Ici, le débit s'échelonne bien. Note : NTttcp fait quelque chose de bizarre sur le port 6001 avant d'ouvrir la connexion de test. Je ne suis pas sûr de ce qui se passe ici.
  • Une trace de données FTP, téléchargeant 20MB de /dev/urandom sur un hôte linux presque identique (1.2.3.6) en utilisant Cygwin ncftp . Là encore, il y a une limite. Le schéma est à peu près le même avec Windows Filezilla.

Changer le iperf La longueur de la mémoire tampon apporte la différence attendue au graphique de la séquence temporelle (beaucoup plus de sections verticales), mais le débit réel reste inchangé.

1voto

spricer Points 21

Je vois que ce message est un peu plus ancien, mais il pourrait aider d'autres personnes.

En bref, vous devez activer le "réglage automatique de la fenêtre de réception" :

netsh int tcp set global autotuninglevel=normal

CTCP n'a aucun intérêt s'il n'est pas activé.

Si vous désactivez "Receive Window Auto-Tuning", vous serez bloqué à une taille de paquet de 64KB, ce qui a un impact négatif sur les longs RTT dans les connexions à haut débit. Vous pouvez également expérimenter avec les options "restricted" et "highlyrestricted".

Très bonne référence : https://www.duckware.com/blog/how-Windows-is-killing-internet-download-speeds/index.html

1voto

Andy Balaam Points 111

J'ai rencontré un problème similaire avec les clients Windows (Windows 7). J'ai effectué la plupart des opérations de débogage que vous avez effectuées, en désactivant l'algorithme de Nagle, le TCP Chimney Offloading, et des tonnes d'autres changements de paramètres liés au TCP. Aucun d'entre eux n'a eu d'effet.

La modification de la fenêtre d'envoi par défaut dans le registre du service AFD m'a permis de résoudre le problème. Le problème semble être lié au fichier afd.sys. J'ai testé plusieurs clients, certains présentaient un téléchargement lent, d'autres non, mais tous étaient des machines Windows 7. Les machines qui présentaient le comportement lent avaient la même version d'AFD.sys. La solution de contournement du registre est nécessaire pour les ordinateurs dotés de certaines versions d'AFD.sys (désolé, je ne me souviens pas des numéros de version).

HKLM \CurrentControlSet\Services\AFD\Parameters

Ajouter - DWORD - DefaultSendWindow

Valeur - Décimale - 1640960

C'est une valeur que j'ai trouvée ici : https://helpdesk.egnyte.com/hc/en-us/articles/201638254-Upload-Speed-Slow-over-WebDAV-Windows-

Je pense que pour utiliser la bonne valeur, vous devez la calculer vous-même en utilisant :

eg. Chargement annoncé : 15 Mbps = 15 000 Kbps

(15000 / 8 ) * 1024 = 1920000

D'après ce que j'ai compris, les logiciels clients devraient généralement remplacer ce paramètre dans le registre, mais s'ils ne le font pas, la valeur par défaut est utilisée, et apparemment la valeur par défaut est très faible dans certaines versions du fichier AFD.sys.

J'ai remarqué que la plupart des produits MS avaient un problème de lenteur lors de l'upload (IE, Mini-redirector(WebDAV), FTP via Windows Explorer, etc...) Lorsque j'utilisais un logiciel tiers (ex. Filezilla), je n'avais pas les mêmes ralentissements.

AFD.sys affecte toutes les connexions Winsock, donc ce correctif devrait s'appliquer à FTP, HTTP, HTTPS, etc...

De plus, cette solution a été mentionnée quelque part, donc je ne veux pas m'en attribuer le mérite si elle fonctionne pour quelqu'un, mais il y avait tellement d'informations dans ce fil de discussion que j'ai eu peur qu'elles aient été négligées.

0voto

André Fernandes Points 919

J'ai moi-même été confronté à une situation similaire (ma question ici ), et j'ai finalement dû désactiver l'heuristique de mise à l'échelle de TCP, définir manuellement le profil d'autoréglage et activer CTCP :

# disable heuristics
C:\Windows\system32>netsh interface tcp set heuristics wsh=disabled
Ok.

# enable receive-side scaling
C:\Windows\system32>netsh int tcp set global rss=enabled
Ok.

# manually set autotuning profile
C:\Windows\system32>netsh interface tcp set global autotuning=experimental
Ok. 

# set congestion provider
C:\Windows\system32>netsh interface tcp set global congestionprovider=ctcp
Ok.

0voto

Chris Stankevitz Points 341

Je n'ai pas assez de points pour commenter, je vais donc poster une "réponse" à la place. J'ai ce qui semble être un problème similaire/identique (voir la question du défaut de serveur ici ). Mon problème (et probablement le vôtre) est le tampon d'envoi du client iperf sous Windows. Il ne dépasse pas 64 KB. Windows est censé augmenter dynamiquement la mémoire tampon lorsqu'elle n'est pas explicitement dimensionnée par le processus. Mais cette croissance dynamique ne se produit pas.

Je ne suis pas sûr de votre graphique de mise à l'échelle de la fenêtre qui montre que la fenêtre s'ouvre jusqu'à 500 000 octets pour votre cas Windows "lent". Je m'attendais à ce que ce graphique ne s'ouvre qu'à ~64 000 octets étant donné que vous êtes limité à 5 Mbps.

0voto

wicksee Points 1

C'est un sujet fascinant qui correspond exactement aux problèmes que j'ai rencontrés en utilisant Win7/iperf pour tester le débit sur de longs tuyaux.

La solution pour Windows 7 est d'exécuter la commande suivante sur le serveur iperf ET sur le client.

netsh interface tcp set global autotuninglevel=experimental

NB : Avant d'effectuer cette opération, veillez à enregistrer l'état actuel de l'autoréglage :

netsh interface tcp show global

Niveau d'accord automatique de la fenêtre de réception : désactivé

Exécutez ensuite le serveur/client iperf à chaque extrémité du tuyau.

Réinitialisez la valeur de l'autoréglage à la suite de vos tests :

netsh interface tcp set global autotuninglevel=

   autotuninglevel - One of the following values:
                     disabled: Fix the receive window at its default
                         value.
                     highlyrestricted: Allow the receive window to
                         grow beyond its default value, but do so
                         very conservatively.
                     restricted: Allow the receive window to grow
                         beyond its default value, but limit such
                         growth in some scenarios.
                     normal: Allow the receive window to grow to
                         accomodate almost all scenarios.
                     experimental: Allow the receive window to grow
                         to accomodate extreme scenarios.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X