2010-06-08 23 views
3

J'ai une application client/serveur (Java) que je migre de Solaris vers RH Linux. depuis que j'ai commencé à l'exécuter dans RH, j'ai remarqué quelques problèmes liés à la latence. J'ai réussi à isoler le problème qui ressemble à ceci:Migration de Solaris vers RH: problème de latence réseau, taille de la fenêtre tcp et autres paramètres tcp

  • client envoie 5 messages (32 octets chacun) dans une rangée (même horodatage d'application) au serveur.
  • messages d'échos de serveur.
  • Le client reçoit des réponses et imprime le temps d'aller-retour pour chaque msg.

Solaris, tout va bien: je reçois TOUS 5 réponses en même temps, à peu près 80ms après avoir envoyé des messages originaux (serveur client & sont plusieurs milliers de miles de l'autre: mon ping RTT est 80ms, tout Ordinaire). En RH, les 3 premiers messages sont renvoyés normalement (ils arrivent 80ms après leur envoi), mais les 2 suivants arrivent 80ms plus tard (soit un RTT total de 160 ms).

le motif est toujours le même. clairement ressemblait à un problème TCP.

sur ma boîte de solaris, j'avais déjà configuré la pile tcp avec 2 options spécifiques:

  1. désactiver algorithme Nagle globalement
  2. ensemble tcp_deferred_acks_max à 0

sur RH, il est impossible pour désactiver globalement nagle, mais je l'ai désactivé sur toutes les sockets de mes applications (TCP_NODELAY).

donc je commencé à jouer avec tcpdump (sur la machine serveur), et comparé les deux sorties:

SOLARIS:

22 2.085645 client   server   TCP  56150 > 6006 [PSH, ACK] Seq=111 Ack=106 Win=66672 Len=22 "MSG_1 RCV" 
23 2.085680 server   client   TCP  6006 > 56150 [ACK] Seq=106 Ack=133 Win=50400 Len=0 
24 2.085908 client   server   TCP  56150 > 6006 [PSH, ACK] Seq=133 Ack=106 Win=66672 Len=22 "MSG_2 RCV" 
25 2.085925 server   client   TCP  6006 > 56150 [ACK] Seq=106 Ack=155 Win=50400 Len=0 
26 2.086175 client   server   TCP  56150 > 6006 [PSH, ACK] Seq=155 Ack=106 Win=66672 Len=22 "MSG_3 RCV" 
27 2.086192 server   client   TCP  6006 > 56150 [ACK] Seq=106 Ack=177 Win=50400 Len=0 
28 2.086243 server   client   TCP  6006 > 56150 [PSH, ACK] Seq=106 Ack=177 Win=50400 Len=21 "MSG_1 ECHO" 
29 2.086440 client   server   TCP  56150 > 6006 [PSH, ACK] Seq=177 Ack=106 Win=66672 Len=22 "MSG_4 RCV" 
30 2.086454 server   client   TCP  6006 > 56150 [ACK] Seq=127 Ack=199 Win=50400 Len=0 
31 2.086659 server   client   TCP  6006 > 56150 [PSH, ACK] Seq=127 Ack=199 Win=50400 Len=21 "MSG_2 ECHO" 
32 2.086708 client   server   TCP  56150 > 6006 [PSH, ACK] Seq=199 Ack=106 Win=66672 Len=22 "MSG_5 RCV" 
33 2.086721 server   client   TCP  6006 > 56150 [ACK] Seq=148 Ack=221 Win=50400 Len=0 
34 2.086947 server   client   TCP  6006 > 56150 [PSH, ACK] Seq=148 Ack=221 Win=50400 Len=21 "MSG_3 ECHO" 
35 2.087196 server   client   TCP  6006 > 56150 [PSH, ACK] Seq=169 Ack=221 Win=50400 Len=21 "MSG_4 ECHO" 
36 2.087500 server   client   TCP  6006 > 56150 [PSH, ACK] Seq=190 Ack=221 Win=50400 Len=21 "MSG_5 ECHO" 
37 2.165390 client   server   TCP  56150 > 6006 [ACK] Seq=221 Ack=148 Win=66632 Len=0 
38 2.166314 client   server   TCP  56150 > 6006 [ACK] Seq=221 Ack=190 Win=66588 Len=0 
39 2.364135 client   server   TCP  56150 > 6006 [ACK] Seq=221 Ack=211 Win=66568 Len=0 

REDHAT:

17 2.081163 client   server   TCP  55879 > 6006 [PSH, ACK] Seq=111 Ack=106 Win=66672 Len=22 "MSG_1 RCV" 
18 2.081178 server   client   TCP  6006 > 55879 [ACK] Seq=106 Ack=133 Win=5888 Len=0 
19 2.081297 server   client   TCP  6006 > 55879 [PSH, ACK] Seq=106 Ack=133 Win=5888 Len=21 "MSG_1 ECHO" 
20 2.081711 client   server   TCP  55879 > 6006 [PSH, ACK] Seq=133 Ack=106 Win=66672 Len=22 "MSG_2 RCV" 
21 2.081761 client   server   TCP  55879 > 6006 [PSH, ACK] Seq=155 Ack=106 Win=66672 Len=22 "MSG_3 RCV" 
22 2.081846 server   client   TCP  6006 > 55879 [PSH, ACK] Seq=127 Ack=177 Win=5888 Len=21 "MSG_2 ECHO" 
23 2.081995 server   client   TCP  6006 > 55879 [PSH, ACK] Seq=148 Ack=177 Win=5888 Len=21 "MSG_3 ECHO" 
24 2.082011 client   server   TCP  55879 > 6006 [PSH, ACK] Seq=177 Ack=106 Win=66672 Len=22 "MSG_4 RCV" 
25 2.082362 client   server   TCP  55879 > 6006 [PSH, ACK] Seq=199 Ack=106 Win=66672 Len=22 "MSG_5 RCV" 
26 2.082377 server   client   TCP  6006 > 55879 [ACK] Seq=169 Ack=221 Win=5888 Len=0 
27 2.171003 client   server   TCP  55879 > 6006 [ACK] Seq=221 Ack=148 Win=66632 Len=0 
28 2.171019 server   client   TCP  6006 > 55879 [PSH, ACK] Seq=169 Ack=221 Win=5888 Len=42 "MSG_4 ECHO + MSG_5 ECHO" 
29 2.257498 client   server   TCP  55879 > 6006 [ACK] Seq=221 Ack=211 Win=66568 Len=0 

donc, J'ai eu confirmation que les choses ne fonctionnent pas correctement pour RH: le paquet 28 est envoyé TROP TARD, il ressemble le serveur attend l'ACK du paquet 27 avant de faire quoi que ce soit.

me semble que c'est la raison la plus probable ...

je réalise que les paramètres « Win » sont différents sur les haldes Solaris & RH: 50400 sur Solaris, seulement 5888 sur RH. c'est un autre indice ...

J'ai lu la doc sur la fenêtre coulissante & fenêtre tampon, et joué avec le rcvBuffer & sendBuffer en java sur mes prises, mais jamais réussi à changer cette valeur 5888 à toute autre chose (j'ai vérifié chaque fois directement avec tcpdump).

Est-ce que quelqu'un sait comment faire cela? J'ai du mal à obtenir des informations définitives, car dans certains cas il y a une "auto-négociation" que je pourrais avoir besoin de contourner, etc ...

J'ai finalement réussi à obtenir seulement partiellement débarrassé de mon problème initial en mettant le paramètre "tcp_slow_start_after_idle" à 0 sur RH, mais il n'a pas changé du tout le paramètre "win". le même problème était là pour les 4 premiers groupes de 5 messages, avec TCP retransmission & TCP Dup ACK dans tcpdump, alors le problème a disparu complètement pour tous les groupes suivants de 5 messages.

Cela ne me semble pas une solution très propre et/ou générique. J'aimerais vraiment reproduire exactement les mêmes conditions sous les deux systèmes d'exploitation.

Je continuerai à faire des recherches, mais toute aide des gourous TCP serait grandement appréciée!

+0

La trace ne correspond pas à votre description. La trace redhat prend moins de temps que Solaris, donc je ne vois pas de problèmes de latence. Aussi l'écho est si rapide (moins de 1 ms) donc il semble que cela soit fait sur un loopback ou un LAN. –

+0

timestamps sur le côté gauche ne peut pas être comparé (entre solaris & RH), ils sont simplement relatifs au moment où le premier paquet a été reçu (je pense) DANS CHAQUE BOÎTE, ce qui peut être à peu près n'importe quand. les tests ne sont pas effectués en même temps. le problème est le temps de réponse entre la réception de MSG et la réponse d'écho, mesurée sur le SERVEUR. sur solaris, tous les échos sont envoyés dans environ 2ms de la réception du premier msg (2.087500 - 2.085645 = 0.001855) sur RH, 4ème et 5ème échos sont envoyés 90ms plus tard (2.171019 - 2.081163) – Bastien

Répondre

1

Il semble que l'algorithme d'évitement de la congestion est en train d'apparaître sur la boîte Red Hat.

Notez que comme paquet de 26, le serveur a vu et tout ACKed du client, mais le client n'a ACKed SYN initial du serveur - il n'a pas ACKed une des messages du serveur encore. Notez également que le paquet 27, qui redémarre les choses, est le client qui reconnaît les deux premiers lots de données du serveur (paquets 19 et 22).

Quel algorithme de contrôle de congestion est utilisé par la boîte Red Hat? (/proc/sys/net/ipv4/tcp_congestion_control) - vous pouvez essayer de passer à l'un des autres disponibles.

+0

oui c'est le point que je suis préoccupé, je vois que beaucoup d'échos ne sont pas acceptés par le client, et j'imagine qu'un mécanisme empêche le serveur d'envoyer quoi que ce soit jusqu'à ce que les ACK soient reçus: il n'envoie que les 4ème et 5ème écho après réception d'un ACK. juste ne sais pas trop ce qui cause ce mécanisme et comment l'influencer. va jouer avec le contrôle de la congestion, actuellement c'est "cubique", va chercher ... merci! – Bastien

+0

@Bastien: Essayez de le paramétrer sur "reno" (juste "echo" reno ">/proc/sys/net/ipv4/tcp_congestion_control') et voyez si vous aimez mieux ce comportement. – caf

+0

l'a changé en "reno", aucun changement de comportement du tout ... – Bastien