15 votes

Est-il dangereux de modifier la valeur de /proc/sys/net/ipv4/tcp_tw_reuse ?

Nous avons quelques systèmes de production qui ont été récemment convertis en machines virtuelles. Une de nos applications accède fréquemment à une base de données MySQL, et pour chaque requête, elle crée une connexion, interroge et déconnecte cette connexion.

Ce n'est pas la bonne façon d'interroger (je sais), mais nous avons des contraintes que nous n'arrivons pas à contourner. Quoi qu'il en soit, le problème est le suivant : lorsque la machine était un hôte physique, le programme fonctionnait correctement. Une fois converti en machine virtuelle, nous avons remarqué des problèmes intermittents de connexion à la base de données. À un moment donné, il y avait plus de 24 000 connexions de socket dans TIME_WAIT (sur l'hôte physique, le maximum que j'ai vu était de 17 000 - ce qui n'est pas bon, mais ne pose pas de problème).

J'aimerais que ces connexions soient réutilisées, afin d'éviter ce problème de connexion, etc :

Questions :

Est-il possible de fixer la valeur de tcp_tw_reuse à 1 ? Quels sont les dangers évidents ? Y a-t-il une raison pour laquelle je devrais jamais le faire ?

Existe-t-il un autre moyen de faire en sorte que le système (RHEL/CentOS) empêche un si grand nombre de connexions de passer en TIME_WAIT, ou qu'elles soient réutilisées ?

Enfin, que ferait la modification de tcp_tw_recycle, et est-ce que cela m'aiderait ?

D'avance, merci !

10voto

duffbeer703 Points 19867

Vous pouvez réduire le temps en toute sécurité, mais vous risquez de rencontrer des problèmes avec des connexions mal fermées sur des réseaux avec perte de paquets ou gigue. Je ne commencerais pas à régler le temps à 1 seconde, mais plutôt à 15-30 et à descendre progressivement.

Par ailleurs, il faut vraiment que vous corrigiez votre candidature.

RFC 1185 contient une bonne explication à la section 3.2 :

Lorsqu'une connexion TCP est fermée, un délai de 2*MSL dans TIME-WAIT immobilise la paire de sockets pendant 4 minutes (voir la section 3.5 du document [Postel81]. Les applications basées sur TCP qui ferment une connexion et en ouvrent une nouvelle (par exemple, une connexion de transfert de données FTP utilisant le mode Stream) doivent choisir une nouvelle paire de sockets à chaque fois. Ce délai sert deux objectifs différents :

 (a)  Implement the full-duplex reliable close handshake of TCP. 

      The proper time to delay the final close step is not really 
      related to the MSL; it depends instead upon the RTO for the 
      FIN segments and therefore upon the RTT of the path.* 
      Although there is no formal upper-bound on RTT, common 
      network engineering practice makes an RTT greater than 1 
      minute very unlikely.  Thus, the 4 minute delay in TIME-WAIT 
      state works satisfactorily to provide a reliable full-duplex 
      TCP close.  Note again that this is independent of MSL 
      enforcement and network speed. 

      The TIME-WAIT state could cause an indirect performance 
      problem if an application needed to repeatedly close one 
      connection and open another at a very high frequency, since 
      the number of available TCP ports on a host is less than 
      2**16.  However, high network speeds are not the major 
      contributor to this problem; the RTT is the limiting factor 
      in how quickly connections can be opened and closed. 
      Therefore, this problem will no worse at high transfer 
      speeds. 

 (b)  Allow old duplicate segements to expire. 

      Suppose that a host keeps a cache of the last timestamp 
      received from each remote host.  This can be used to reject 
      old duplicate segments from earlier incarnations of the 

*Remarque : on pourrait faire valoir que la partie qui envoie une FIN sait à quel degré de rumeur elle est soumise. le degré de fiabilité dont il a besoin, et qu'il devrait donc être en mesure de déterminer la longueur de la TIME-WAIT pour le destinataire du FIN. destinataire. Il pourrait s'agir de avec une option TCP appropriée. appropriée dans les segments FIN.

      connection, if the timestamp clock can be guaranteed to have 
      ticked at least once since the old conennection was open. 
      This requires that the TIME-WAIT delay plus the RTT together 
      must be at least one tick of the sender's timestamp clock. 

      Note that this is a variant on the mechanism proposed by 
      Garlick, Rom, and Postel (see the appendix), which required 
      each host to maintain connection records containing the 
      highest sequence numbers on every connection.  Using 
      timestamps instead, it is only necessary to keep one quantity 
      per remote host, regardless of the number of simultaneous 
      connections to that host.

9voto

user64756 Points 366

Je pense qu'il n'y a pas de problème à changer cette valeur à 1. Une manière plus appropriée serait d'utiliser la commande :

[root@server]# sysctl -w net.ipv4.tcp_tw_reuse=1

À ma connaissance, il n'y a pas de danger évident, mais une recherche rapide sur Google permet d'obtenir ce qui suit lien qui affirme que tcp_tw_reuse est la meilleure alternative à tcp_tw_recycle mais doit être utilisé avec prudence.

8voto

Mark Wittenberg Points 61

Cela ne répond pas à votre question (et c'est avec 18 mois de retard), mais suggère une autre façon de faire en sorte que votre ancienne application réutilise les ports :

Une alternative utile à la mise en place tcp_tw_reuse (ou tcp_tw_recycle ) sur le système est d'insérer une bibliothèque partagée (à l'aide de LD_PRELOAD ) dans votre application ; cette bibliothèque peut alors permettre la réutilisation du port. Cela permet à votre ancienne application de permettre la réutilisation du port sans l'imposer à toutes les applications de votre système (aucune modification de votre application n'est nécessaire), ce qui limite l'impact de votre modification. Par exemple,

    LD_PRELOAD=/opt/local/lib/libreuse.so ./legacy_app

Cette bibliothèque partagée doit intercepter le socket() appeler le vrai socket(), et mettre SO_REUSEADDR et/ou SO_REUSEPORT sur le socket retourné. Regardez http://libkeepalive.sourceforge.net pour un exemple de la façon de procéder (cela active les keepalives, mais l'activation de SO_REUSEPORT est très similaire). Si votre application patrimoniale mal élevée utilise IPv6, n'oubliez pas de modifier la ligne 55 de libkeepalive.c de

    if((domain == PF_INET) && (type == SOCK_STREAM)) {

à

    if(((domain == PF_INET) || (domain == PF_INET6)) && (type == SOCK_STREAM)) {

Si vous êtes bloqué, envoyez-moi un courriel et j'écrirai le code et vous l'enverrai.

0voto

jcollum Points 10236

La connexion ne peut pas être réutilisée si elle est en attente. Si vous n'avez pas de perte de paquets sur le réseau entre l'application et MySQL, vous pouvez réduire le délai d'attente.

Cependant, la meilleure solution consiste à utiliser des connexions persistantes vers la base de données et un pool de connexions.

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