Struktura gniazda jądra i TCP_DIAG

18

Pracuję na oprogramowaniu, które łączy się z serwerem danych w czasie rzeczywistym (za pomocą TCP) i mam przerwane połączenia. Domyślam się, że klienci nie czytają wystarczająco szybko danych pochodzących z serwera. Dlatego chciałbym monitorować moje gniazda TCP. W tym celu znalazłem narzędzie „ss”.

To narzędzie pozwala zobaczyć stan każdego gniazda - oto przykładowy wiersz danych wyjściowych polecenia ss -inm 'src *:50000'

ESTAB      0      0             184.7.60.2:50000       184.92.35.104:1105
  mem:(r0,w0,f0,t0) sack rto:204 rtt:1.875/0.75 ato:40

Moje pytanie brzmi: co oznacza część pamięci? Patrząc na kod źródłowy narzędzia stwierdziłem, że dane pochodzą ze struktury jądra ( sockin sock.h). Dokładniej, pochodzi z pól:

r = sk->sk_rmem_alloc
w = sk->sk_wmem_queued;
f = sk->sk_forward_alloc;
t = sk->sk_wmem_alloc;

Czy ktoś wie, co mają na myśli? Moje domysły to:

  • rmem_alloc : rozmiar bufora wejściowego
  • wmem_alloc : rozmiar bufora wychodzącego
  • sk_forward_alloc : ???
  • sk->sk_wmem_queued : ???

Oto moje rozmiary buforów:

net.ipv4.tcp_rmem = 4096        87380   174760
net.ipv4.tcp_wmem = 4096        16384   131072
net.ipv4.tcp_mem = 786432       1048576 1572864
net.core.rmem_default = 110592
net.core.wmem_default = 110592
net.core.rmem_max = 1048576
net.core.wmem_max = 131071
Tornado
źródło
Jaka jest twoja konfiguracja rozmiaru bufora? Czy widzisz bufory odbiorcze nasycane na połączeniach gniazd? Czy twoja strona zrywa połączenie z EWOULDBLOCK?
Karlson,
Wydaje mi się, że moje rozmiary gniazd są dość małe, zaktualizowałem o nich post. W przypadku EWOULDBLOCK nie mogę powiedzieć. Mój klient jest w JAVA i po prostu powiedział, że został odłączony przez serwer. Serwer jest w C ++ i po prostu mówi, że porzucił połączenie bez żadnych informacji. Nie mam kodu źródłowego serwera, więc nie mogę zmienić jego zachowania. Wygląda na to, że klienci zostają rozłączeni, gdy są nieco przeciążeni, nawet jeśli trwa to tylko kilka sekund.
Twister
Czy konfiguracja rozmiarów buforów jest regulowana na serwerze? Czy możesz oglądać rozmiary buforów na kliencie? Czy masz dostęp do źródła klienta? Czy uruchomiłeś program netstat -apnc, aby obserwować rozmiary buforów? Czy próbowałeś zwiększyć rozmiary buforów w jądrze, aby zobaczyć, co się stanie?
Karlson,
Tak, są i są już ustawione na maksymalną wartość serwera (uważam, że nie mogą być większe niż właściwości net.ipv4.tcp_ *, prawda?) W przypadku netstat -apnc nie podaje mi rozmiarów buforów, dlatego spojrzałem na ss. W przypadku jądra nie jestem rootem na serwerze, a zespoły IT tutaj są dość uparte. Muszę się upewnić, co się stanie, zanim poproszę ich o zmianę wartości ... I tak, mam dostęp do źródła klienta, a moje dochodzenie w sprawie klienta potwierdza, że ​​rozłączenie pochodzi z serwera.
Twister
netstat -apnc daje całkowity rozmiar kolejek wysyłania i odbierania w systemie Linux. Jeśli serwer ustawia bufor na maksymalną dostępną i nadal się nasycasz, być może potrzebujesz wyższych ustawień bufora na poziomie systemu operacyjnego
Karlson

Odpowiedzi:

7

sk_forward_alloc jest przydzieloną do przodu pamięcią, która jest całkowitą pamięcią aktualnie dostępną w przydziale gniazda.

sk_wmem_queued jest ilością pamięci używanej przez bufor wysyłający gniazda w kolejce w kolejce nadawczej i albo nie zostały jeszcze wysłane, albo nie zostały jeszcze potwierdzone.

Więcej informacji na temat zarządzania pamięcią TCP można znaleźć w rozdziale 9 architektury, projektowania i wdrażania TCP / IP w systemie Linux Autor: Sameer Seth, M. Ajaykumar Venkatesulu

aculich
źródło
Nie rozumiem, czym sk_wmem_queuedróżni się ta definicja sk_wmem_alloc, czy mógłbyś trochę rozwinąć tę kwestię? (Jeśli znasz odpowiedź, dodaj odpowiedź na to pytanie: unix.stackexchange.com/questions/551444/... )
mały koleś
1

Zobacz stronę podręcznika ss.

<fwd_alloc>
   The  memory allocated by the socket as cache, but not used for receiving/sending packet yet. If need memory to send/receive packet, the memory in this cache will be used before allocate additional memory.

<wmem_queued>
   The memory allocated for sending packet (which has not been sent to layer 3)
wenjianhn
źródło
0

Jeśli chodzi o sk_wmem_queuedi sk_wmem_alloc, zadałem to samo pytanie, więc skopiuję odpowiedź tutaj:

Wysłałem e-mail do Erica Dumazeta, który przyczynia się do stosu sieciowego Linuksa, a oto odpowiedź:

sk_wmem_allocśledzi liczbę bajtów dla skb w kolejce po stosie transportu: warstwa qdisc i bufory pierścieniowe NIC TX.

Jeśli masz 1 MB danych w kolejce zapisu TCP, jeszcze nie wysłane (limit cwnd), sk_wmem_queuebędzie to około 1 MB, ale sk_wmem_allocbędzie około 0

Bardzo dobrym dokumentem do zrozumienia, jakie są te trzy typy kolejek (bufor gniazd, kolejka qdisc i kolejka urządzeń), jest ten artykuł (raczej długi) . Krótko mówiąc, gniazdo zaczyna się od wypchnięcia pakietów bezpośrednio do kolejki qdisc, która przesyła je do kolejki urządzeń. Gdy kolejka qdisc jest pełna, gniazdo zaczyna buforować dane we własnej kolejce zapisu.

stos sieciowy umieszcza pakiety bezpośrednio w dyscyplinie kolejkowania lub odpycha z powrotem na górne warstwy (np. bufor gniazda), jeśli kolejka jest pełna

Więc w zasadzie: sk_wmem_queuesjest pamięć używana przez bufor pamięci ( sock.sk_write_queue), podczas gdy sk_wmem_allocjest pamięć wykorzystywana przez pakiety w qdisc i kolejkach urządzeń.

mały ziomek
źródło