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

9

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

Não é a maneira apropriada de consultar (eu sei), mas temos restrições que não parecem conseguir contornar. De qualquer forma, o problema é este: enquanto a máquina era um host físico, o programa funcionava bem. Uma vez convertido para uma máquina virtual, notamos problemas de conexão intermitente com o banco de dados. Houve, em um ponto, mais de 24.000 conexões de socket em TIME_WAIT (no host físico, o máximo que eu vi foi 17.000 - não bom, mas não causando problemas).

Gostaria que essas conexões fossem reutilizadas, para que não víssemos esse problema de conexão e, portanto:

Perguntas:

Está certo definir o valor de tcp_tw_reuse como 1? Quais são os perigos óbvios? Existe alguma razão pela qual eu deveria nunca fazer isso?

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

Por último, o que mudaria o tcp_tw_recycle, e isso me ajudaria?

Antecipadamente, obrigado!

    
por Sagar 11.02.2011 / 21:06

4 respostas

8

Você pode reduzir o tempo de forma segura, mas pode encontrar problemas com conexões fechadas em redes com perda de pacotes ou jitter. Eu não começaria a sintonizar em 1 segundo, começaria em 15-30 e continuaria descendo.

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

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

When a TCP connection is closed, a delay of 2*MSL in TIME-WAIT state ties up the socket pair for 4 minutes (see Section 3.5 of [Postel81]. Applications built upon TCP that close one connection and open a new one (e.g., an FTP data transfer connection using Stream mode) must choose a new socket pair each time. This delay serves two different purposes:

 (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 

*Note: It could be argued that the side that is sending a FIN knows what degree of reliability it needs, and therefore it should be able to determine the length of the TIME-WAIT delay for the FIN's recipient. This could be accomplished with an appropriate TCP option in FIN segments.

      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.
    
por 17.02.2011 / 03:43
6

Isso não responde à sua pergunta (e está com 18 meses de atraso), mas sugere outra maneira de tornar suas portas de reutilização de aplicativos herdadas:

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

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

Esta biblioteca compartilhada deve interceptar a chamada socket() , chamar o soquete real () e definir SO_REUSEADDR e / ou SO_REUSEPORT no soquete retornado. Veja o link para ver um exemplo de como fazer isso (isso ativa os keepalives, mas ativar SO_REUSEPORT é muito parecido). Se o seu aplicativo legado mal-comportado usar o IPv6, lembre-se de alterar a linha 55 de libkeepalive.c de

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

para

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

Se você está preso, envie-me um e-mail e eu escrevo o código e envio para você.

    
por 16.11.2012 / 00:51
5

Acho que é bom alterar este 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 este link que afirma que tcp_tw_reuse é a melhor alternativa que tcp_tw_recycle , mas deve ser usado com cautela independentemente.

    
por 17.02.2011 / 03:05
0

A conexão não pode ser reutilizada se estiver em TIME WAIT. Se você não tem perda de pacotes na rede entre o aplicativo e o MySQL, você pode diminuir o tempo limite.

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

    
por 14.02.2011 / 20:22