Come ridurre il numero di socket in TIME_WAIT?


36

Ubuntu Server 10.04.1 x86

Ho una macchina con un servizio HTTP FCGI dietro nginx, che serve molte piccole richieste HTTP a molti client diversi. (Circa 230 richieste al secondo nelle ore di punta, la dimensione media della risposta con le intestazioni è di 650 byte, diversi milioni di client diversi al giorno).

Di conseguenza, ho molti socket, sospesi in TIME_WAIT (il grafico viene catturato con le impostazioni TCP di seguito):

TEMPO DI ATTESA

Vorrei ridurre il numero di socket.

Cosa posso fare oltre a questo?

$ cat / proc / sys / net / ipv4 / tcp_fin_timeout
1
$ cat / proc / sys / net / ipv4 / tcp_tw_recycle
1
$ cat / proc / sys / net / ipv4 / tcp_tw_reuse
1

Aggiornamento: alcuni dettagli sul layout di servizio effettivo sulla macchina:

client ----- TCP-socket -> nginx (proxy inverso del bilanciamento del carico) 
       ----- TCP-socket -> nginx (worker) 
       --domain-socket -> software fcgi
                          --single-persistent-TCP-socket -> Redis
                          --single-persistent-TCP-socket -> MySQL (altra macchina)

Probabilmente dovrei cambiare il bilanciamento del carico -> connessione del lavoratore anche ai socket di dominio, ma il problema relativo ai socket TIME_WAIT rimarrebbe - ho intenzione di aggiungere presto un secondo lavoratore su una macchina separata. In questo caso non sarà possibile utilizzare socket di dominio.


Sembra che Munin stia mentendo spudoratamente. Vedi i commenti alla risposta di Kyle. Esaminandolo ora.
Alexander Gladysh,

1
Ha

Ora sembra che Munin non stia mentendo, ma piuttosto sto guardando la trama sbagliata ...
Alexander Gladysh,

Risposte:


28

Una cosa che dovresti fare per iniziare è riparare il net.ipv4.tcp_fin_timeout=1. È troppo basso, probabilmente non dovresti prenderlo molto più in basso di 30.

Dal momento che questo è dietro nginx. Significa che nginx agisce come proxy inverso? In tal caso, le connessioni sono 2x (una al client, una ai server Web). Sai a quale estremità appartengono queste prese?

Aggiornamento:
fin_timeout è quanto tempo rimangono in FIN-WAIT-2 (da networking/ip-sysctl.txtnella documentazione del kernel):

tcp_fin_timeout - INTEGER
        Time to hold socket in state FIN-WAIT-2, if it was closed
        by our side. Peer can be broken and never close its side,
        or even died unexpectedly. Default value is 60sec.
        Usual value used in 2.2 was 180 seconds, you may restore
        it, but remember that if your machine is even underloaded WEB server,
        you risk to overflow memory with kilotons of dead sockets,
        FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,
        because they eat maximum 1.5K of memory, but they tend
        to live longer. Cf. tcp_max_orphans.

Penso che forse devi solo lasciare che Linux mantenga il numero del socket TIME_WAIT confrontato con quello che sembra forse un limite di 32k su di loro ed è qui che Linux li ricicla. Questo 32k è accennato in questo link :

Inoltre, trovo confuso / proc / sys / net / ipv4 / tcp_max_tw_buckets. Anche se il valore predefinito è 180000, vedo un'interruzione TCP quando sul mio sistema sono presenti socket TIME_WAIT da 32K, indipendentemente dal numero massimo di bucket.

Questo link suggerisce anche che lo stato TIME_WAIT è di 60 secondi e non può essere sintonizzato tramite proc.


Curiosità casuale: puoi vedere i timer sul timewait con netstat per ogni socket connetstat -on | grep TIME_WAIT | less

Riutilizza Vs Recycle:
sono interessanti, si legge come reuse abilita il riutilizzo di time_Wait socket e recycle lo mette in modalità TURBO:

tcp_tw_recycle - BOOLEAN
        Enable fast recycling TIME-WAIT sockets. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

tcp_tw_reuse - BOOLEAN
        Allow to reuse TIME-WAIT sockets for new connections when it is
        safe from protocol viewpoint. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

Non consiglierei di usare net.ipv4.tcp_tw_recycle in quanto causa problemi con i client NAT .

Forse potresti provare a non averli entrambi accesi e vedere quale effetto ha (provane uno alla volta e vedi come funzionano da soli)? Vorrei utilizzare netstat -n | grep TIME_WAIT | wc -lper un feedback più veloce di Munin.


1
@Kyle: quale valore net.ipv4.tcp_fin_timeoutconsiglieresti?
Alexander Gladysh,

1
@Kyle: client - socket TCP -> nginx (proxy inverso del bilanciamento del carico) - socket TCP -> nginx (lavoratore) - socket di dominio -> software
fcgi

2
Direi 30o forse 20. Provalo e vedi. Hai un sacco di carico, quindi un sacco di TIME_WAIT ha un senso.
Kyle Brandt,

1
@Kyle: scusami per una domanda stupida (purtroppo sono a un livello di culto del carico qui finora, ma cosa dovrei aspettarmi esattamente quando cambio net.ipv4.tcp_fin_timeoutda 1a 20?
Alexander Gladysh,

4
Oh, ecco un bel uno di linea: netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c. Quindi @Alex, se a Munin non piace, magari approfondire il modo in cui controlla queste statistiche. Forse l'unico problema è che Munin ti sta dando dei dati negativi :-)
Kyle Brandt il

1

tcp_tw_reuse è relativamente sicuro in quanto consente il riutilizzo delle connessioni TIME_WAIT.

Inoltre, è possibile eseguire più servizi in ascolto su porte diverse dietro il bilanciamento del carico se rimanere senza porte è un problema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.