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

10

Nous avons quelques systèmes de production qui ont été récemment convertis en machines virtuelles. Il existe une de nos applications qui 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 façon appropriée d'interroger (je sais), mais nous avons des contraintes que nous ne pouvons pas sembler contourner. Quoi qu'il en soit, le problème est le suivant: alors que la machine était un hôte physique, le programme s'est bien déroulé. Une fois converti en machine virtuelle, nous avons remarqué des problèmes de connexion intermittents à la base de données. Il y avait, à un moment donné, plus de 24 000 connexions de socket dans TIME_WAIT (sur l'hôte physique, le maximum que j'ai vu était 17 000 - pas bon, mais sans causer de problèmes).

Je voudrais que ces connexions soient réutilisées, afin que nous ne voyions pas ce problème de connexion, et donc:

Des questions:

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

De plus, existe-t-il un autre moyen d'obtenir le système (RHEL / CentOS) pour empêcher autant de connexions d'entrer dans TIME_WAIT ou de les faire réutiliser?

Enfin, que changerait tcp_tw_recycle et cela m'aiderait-il?

D'avance, merci!

Sagar
la source
1
Ce lien explique bien le danger de tcp_tw_recycle et tcp_tw_reuse. Ne l'utilisez pas.

Réponses:

8

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

De plus, vous devez vraiment corriger votre application.

RFC 1185 a une bonne explication dans la section 3.2:

Lorsqu'une connexion TCP est fermée, un retard de 2 * MSL dans l'état TIME-WAIT lie la paire de sockets pendant 4 minutes (voir la section 3.5 de [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) doit choisir une nouvelle paire de sockets à chaque fois. Ce délai sert à deux fins différentes:

 (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 de quel degré de fiabilité elle a besoin et qu'elle devrait donc être en mesure de déterminer la durée du délai d'attente pour le destinataire de la FIN. Cela pourrait être accompli avec une option TCP 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.
duffbeer703
la source
Merci pour l'explication. Le problème est dans la bibliothèque, sur laquelle je n'ai aucun contrôle.
Sagar
6

Cela ne répond pas à votre question (et c'est 18 mois de retard), mais suggère une autre façon de faire réutiliser les ports de votre application héritée:

Une alternative utile à la configuration tcp_tw_reuse(ou tcp_tw_recycle) sur le système consiste à insérer une bibliothèque partagée (à l'aide LD_PRELOAD) dans votre application; cette bibliothèque peut alors permettre la réutilisation du port. Cela rend votre application héritée autorise la réutilisation des ports sans forcer cela sur toutes les applications de votre système (aucune modification de votre application n'est requise), limitant ainsi l'impact de votre ajustement. Par exemple,

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

Cette bibliothèque partagée doit intercepter l' socket()appel, appeler la vraie socket () et définir SO_REUSEADDR et / ou SO_REUSEPORT sur la socket retournée. 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 héritage mal comportés utilise IPv6, pensez à changer la ligne 55 de libkeepalive.cde

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

à

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

Si vous êtes coincé, envoyez-moi un e-mail et j'écrirai le code et vous le ferai parvenir.

Mark Wittenberg
la source
6

Je pense qu'il est correct de changer cette valeur à 1. Une manière plus appropriée pourrait être d'utiliser la commande:

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

Il n'y a aucun danger évident que je sache, mais une recherche rapide sur Google produit ce lien qui affirme que tcp_tw_reusec'est la meilleure alternative que tcp_tw_recycle, mais doit être utilisé avec prudence malgré tout.

atx
la source
2
Non, ce n'est pas ce que ça dit. Il dit (en parlant de tcp_tw_reuse), "C'est généralement une alternative plus sûre à tcp_tw_recycle".
Fantius
0

La connexion ne peut pas être réutilisée si elle est en TIME WAIT. 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.

Mircea Vutcovici
la source
1
En fait, ce n'est pas nécessairement vrai. Certains systèmes autorisent l'utilisation de sockets dans TIME_WAIT, c'est à cela que sert ma question. Pas si c'est possible, mais quels sont les dangers évidents et pas si évidents. Merci!
Sagar