Jak zmniejszyć liczbę gniazd w TIME_WAIT?

36

Ubuntu Server 10.04.1 x86

Mam maszynę z usługą FCGI HTTP za nginx, która obsługuje wiele małych żądań HTTP do wielu różnych klientów. (Około 230 żądań na sekundę w godzinach szczytu, średni rozmiar odpowiedzi z nagłówkami to 650 bajtów, kilka milionów różnych klientów dziennie).

W rezultacie mam wiele gniazd wiszących w TIME_WAIT (wykres jest przechwytywany z ustawieniami TCP poniżej):

CZAS OCZEKIWANIA

Chciałbym zmniejszyć liczbę gniazd.

Co mogę poza tym zrobić?

$ 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

Aktualizacja: niektóre szczegóły dotyczące faktycznego układu usługi na komputerze:

klient ----- gniazdo TCP -> nginx (odwrotne proxy usługi równoważenia obciążenia) 
       ----- Gniazdo TCP -> nginx (pracownik) 
       --domain-socket -> oprogramowanie fcgi
                          --single-persistent-TCP-socket -> Redis
                          --single-persistent-TCP-socket -> MySQL (inna maszyna)

Prawdopodobnie powinienem również przełączyć moduł równoważenia obciążenia -> połączenie robocze na gniazda domeny, ale problem z gniazdami TIME_WAIT pozostanie - planuję wkrótce dodać drugiego pracownika na osobnym komputerze. W takim przypadku nie będzie można używać gniazd domeny.

Alexander Gladysh
źródło
Wygląda na to, że Munin bezwstydnie kłamie. Zobacz komentarze do odpowiedzi Kyle'a. Patrząc na to teraz.
Alexander Gladysh,
1
Utworzono pytanie o Munin: serverfault.com/questions/212200/…
Alexander Gladysh,
Teraz wygląda na to, że Munin nie kłamie, ale raczej patrzę na niewłaściwą fabułę ...
Alexander Gladysh

Odpowiedzi:

28

Jedną z rzeczy, które powinieneś zrobić, aby rozpocząć, jest naprawienie net.ipv4.tcp_fin_timeout=1. To jest droga do niskiego, prawdopodobnie nie powinieneś brać dużo mniej niż 30.

Ponieważ jest to za nginx. Czy to oznacza, że ​​nginx działa jako odwrotny serwer proxy? W takim przypadku Twoje połączenia są 2x (jeden do klienta, jeden do serwerów internetowych). Czy wiesz, do którego końca należą te gniazda?

Aktualizacja:
fin_timeout określa, jak długo pozostają w FIN-WAIT-2 (From networking/ip-sysctl.txtw dokumentacji jądra):

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.

Myślę, że może po prostu musisz pozwolić Linuksowi trzymać numer gniazda TIME_WAIT w porównaniu z czymś, co może wyglądać na 32-krotne ograniczenie na nich, i właśnie tutaj Linux je przetwarza. Do tego 32k nawiązano w tym linku :

Ponadto uważam, że / proc / sys / net / ipv4 / tcp_max_tw_buckets jest mylący. Chociaż domyślną wartością jest 180000, widzę zakłócenie TCP, gdy mam 32K gniazd TIME_WAIT w moim systemie, bez względu na maks. Tw wiadra.

Ten link sugeruje również, że stan TIME_WAIT wynosi 60 sekund i nie można go dostroić za pomocą proc.

Losowy fajny fakt:
możesz zobaczyć liczniki czasu na netstat dla każdego gniazda znetstat -on | grep TIME_WAIT | less

Ponowne użycie Vs Recycle:
Są to dość interesujące, brzmi to jak ponowne użycie umożliwia ponowne użycie gniazd time_Wait, a recykling przełącza je w tryb 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.

Nie polecałbym używania net.ipv4.tcp_tw_recycle, ponieważ powoduje to problemy z klientami NAT .

Może możesz spróbować nie włączyć obu tych urządzeń i zobaczyć, jaki to ma wpływ (Spróbuj pojedynczo i zobacz, jak działają one same)? Chciałbym skorzystać z netstat -n | grep TIME_WAIT | wc -lszybszego niż Munin zwrotnej.

Kyle Brandt
źródło
1
@Kyle: jaką wartość net.ipv4.tcp_fin_timeoutpoleciłbyś?
Alexander Gladysh,
1
@Kyle: klient - gniazdo TCP -> nginx (odwrotne proxy usługi równoważenia obciążenia) - gniazdo TCP -> nginx (pracownik) - gniazdo domeny -> oprogramowanie
fcgi
2
Powiedziałbym, 30a może 20. Wypróbuj i przekonaj się. Masz dużo obciążeń, więc ma sens TIME_WAIT.
Kyle Brandt,
1
@Kyle: Przepraszam za głupie pytanie (jestem na poziomie ciężarowe kultowego tu tak daleko, niestety), ale co dokładnie należy się spodziewać, aby zobaczyć, kiedy zmiany net.ipv4.tcp_fin_timeoutod 1do 20?
Alexander Gladysh,
4
Oh, tu jest ładny jeden liner: netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c. Więc @Alex, jeśli Munin się nie podoba, może drążyć, jak monitoruje te statystyki. Być może jedynym problemem jest to, że Munin podaje złe dane :-)
Kyle Brandt,
1

tcp_tw_reuse jest stosunkowo bezpieczny, ponieważ pozwala na ponowne użycie połączeń TIME_WAIT.

Możesz także uruchomić więcej usług nasłuchujących na różnych portach za modułem równoważenia obciążenia, jeśli problem z brakiem portów.

Andrzej Pasztet
źródło