É perigoso alterar o valor de / proc / sys / net / ipv4 / tcp_tw_reuse?

10

Temos alguns sistemas de produção que foram recentemente convertidos em máquinas virtuais. Existe um aplicativo nosso que freqüentemente acessa um banco de dados MySQL e, para cada consulta, ele cria uma conexão, consulta e desconecta essa conexão.

Não é a maneira apropriada de consultar (eu sei), mas temos restrições que parece que não conseguimos contornar. Enfim, o problema é o seguinte: enquanto a máquina era um host físico, o programa funcionou bem. Depois de convertido em uma máquina virtual, percebemos problemas de conexão intermitentes com o banco de dados. Houve, em um ponto, mais de 24000 conexões de soquete no TIME_WAIT (no host físico, o máximo que vi foi 17000 - não é bom, mas não está causando problemas).

Gostaria que essas conexões fossem reutilizadas, para que não vejamos esse problema de conexão, e assim:

Questões:

É possível definir o valor de tcp_tw_reuse como 1? Quais são os perigos óbvios? Existe alguma razão para eu nunca fazer isso?

Além disso, existe outra maneira de obter o sistema (RHEL / CentOS) para impedir que tantas conexões entrem no TIME_WAIT ou que elas sejam reutilizadas?

Por fim, o que a alteração do tcp_tw_recycle faria e isso me ajudaria?

De antemão, obrigado!

Sagar
fonte
1
Este link explica bem o perigo de tcp_tw_recycle e tcp_tw_reuse. Não use isso.

Respostas:

8

Você pode reduzir o tempo de inatividade com segurança, mas pode ter problemas com conexões fechadas incorretamente em redes com perda ou instabilidade de pacotes. Eu não começaria a sintonizar em 1 segundo, começaria entre 15 e 30 e continuaria trabalhando.

Além disso, você realmente precisa corrigir seu aplicativo.

O RFC 1185 tem uma boa explicação na seção 3.2:

Quando uma conexão TCP é fechada, um atraso de 2 * MSL no estado TIME-WAIT amarra o par de soquetes por 4 minutos (consulte a Seção 3.5 de [Postel81].) Aplicativos criados sobre o TCP que fecham uma conexão e abrem uma nova (por exemplo, , uma conexão de transferência de dados FTP usando o modo Stream) deve escolher um novo par de soquetes a cada vez. Esse atraso serve a dois propósitos diferentes:

 (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 

* Nota: Pode-se argumentar que o lado que está enviando um FIN sabe qual o grau de confiabilidade necessário e, portanto, deve poder determinar a duração do atraso no tempo de espera do destinatário do FIN. Isso pode ser feito com uma opção TCP apropriada nos segmentos 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
fonte
Obrigada pelo esclarecimento. O problema está na biblioteca, sobre a qual eu não tenho controle.
Sagar
6

Isso não responde à sua pergunta (e está 18 meses atrasado), mas sugere outra maneira de tornar as portas de reutilização do seu aplicativo herdado:

Uma alternativa útil para definir tcp_tw_reuse(ou tcp_tw_recycle) no sistema é inserir uma biblioteca compartilhada (usando LD_PRELOAD) no seu aplicativo; essa biblioteca pode permitir a reutilização da porta. Isso faz com que o seu aplicativo herdado permita a reutilização de portas sem forçar isso em todos os aplicativos do seu sistema (nenhuma modificação é necessária), limitando o impacto do seu ajuste. Por exemplo,

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

Essa biblioteca compartilhada deve interceptar a socket()chamada, chamar o soquete real () e definir SO_REUSEADDR e / ou SO_REUSEPORT no soquete retornado. Veja http://libkeepalive.sourceforge.net para obter um exemplo de como fazer isso (isso ativa o keepalives, mas ativar o SO_REUSEPORT é muito semelhante). Se seu aplicativo legado mal-comportado usa IPv6, lembre-se de alterar linha 55 do libkeepalive.cde

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

para

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

Se você estiver emperrado, envie-me um e-mail e eu escreverei o código e o enviarei para você.

Mark Wittenberg
fonte
6

Eu acho que é bom alterar esse valor para 1. Uma maneira mais apropriada pode ser usar o comando:

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

Não há perigos óbvios que eu conheça, mas uma rápida pesquisa no Google produz esse link que afirma tcp_tw_reuseser a melhor alternativa do que tcp_tw_recycle, mas deve ser usado com cautela independentemente.

atx
fonte
2
Não, não é isso que diz. Ele diz (falando sobre tcp_tw_reuse): "Geralmente é uma alternativa mais segura ao tcp_tw_recycle".
Fantius 28/03/2013
0

A conexão não pode ser reutilizada se eles estiverem no TIME WAIT. Se você não tiver perda de pacotes na rede entre o aplicativo e o MySQL, poderá diminuir o tempo limite.

No entanto, a melhor solução é usar conexões persistentes com o banco de dados e um pool de conexões.

Mircea Vutcovici
fonte
1
Na verdade, isso não é necessariamente verdade. Alguns sistemas permitirão o uso de soquetes no TIME_WAIT, que é sobre o que minha pergunta é. Não se é possível, mas quais são os perigos óbvios e não tão óbvios. Obrigado!
Sagar