Struttura del socket del kernel e TCP_DIAG


18

Sto lavorando a un software che si collega a un server di dati in tempo reale (utilizzando TCP) e alcune connessioni si interrompono. La mia ipotesi è che i client non leggano i dati provenienti dal server abbastanza velocemente. Pertanto, vorrei monitorare i miei socket TCP. Per questo ho trovato lo strumento "ss".

Questo strumento consente di vedere lo stato di ogni socket - ecco una riga di esempio dell'output del comando 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

La mia domanda è: cosa significa la parte di memoria? Guardando il codice sorgente dello strumento ho scoperto che i dati provengono da una struttura del kernel ( sockin sock.h). Più precisamente, viene dai campi:

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

Qualcuno sa cosa significano? Le mie ipotesi sono:

  • rmem_alloc : dimensione del buffer in entrata
  • wmem_alloc : dimensione del buffer in uscita
  • sk_forward_alloc : ???
  • sk->sk_wmem_queued : ???

Ecco le dimensioni dei miei buffer:

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

Qual è la tua configurazione della dimensione del buffer? Vedi che i buffer di ricezione si saturano sulle connessioni socket? Il tuo gruppo interrompe la connessione su EWOULDBLOCK?
— Karlson

Le dimensioni delle mie prese sono piuttosto piccole, penso, ho aggiornato il post con loro. Per l'EWOULDBLOCK non posso dirlo. Il mio client è in Java e dico solo che è stato disconnesso dal server. Il server è in C ++ e dice solo che ha lasciato cadere la connessione senza alcuna informazione. Non ho il codice sorgente del server, quindi non posso cambiarne il comportamento. Sembra che i client si disconnettano quando sono un po 'sovraccarichi, anche se durano solo pochi secondi.
— Twister,

La configurazione delle dimensioni del buffer è regolabile sul server? Puoi guardare le dimensioni del buffer sul client? Hai accesso alla fonte del cliente? Hai eseguito netstat -apnc per guardare le dimensioni del buffer? Hai provato ad aumentare le dimensioni del buffer nel kernel per vedere cosa succede?
— Karlson,

Sì, lo sono e sono già impostati sul valore massimo del server (credo che non possano essere più grandi delle proprietà net.ipv4.tcp_ *, giusto?) Per netstat -apnc non mi dà le dimensioni dei buffer, questo è il motivo per cui ho visto SS. Per il kernel non sono root sul server e i team IT qui sono piuttosto testardi. Devo essere sicuro di ciò che accade prima di chiedere loro di modificare i valori ... E sì, ho accesso all'origine client e le mie indagini sul client confermano che la disconnessione proviene dal server.
— Twister,

netstat -apnc ti dà la dimensione totale delle code di invio e ricezione su Linux. Se il server imposta il buffer sul massimo disponibile e stai ancora saturando, forse hai bisogno di impostazioni di buffer più elevate a livello di sistema operativo
— Karlson

Risposte:


7

sk_forward_alloc è la memoria allocata in avanti che è la memoria totale attualmente disponibile nella quota del socket.

sk_wmem_queued è la quantità di memoria utilizzata dal buffer di invio del socket in coda nella coda di trasmissione e non è ancora stata inviata o non è ancora stata riconosciuta.

Puoi saperne di più sulla gestione della memoria TCP nel capitolo 9 di Architettura, progettazione e implementazione TCP / IP in Linux Di Sameer Seth, M. Ajaykumar Venkatesulu


Non capisco come questa definizione di sk_wmem_queueddifferisca da sk_wmem_alloc, potresti espanderci un po 'su questo? (Se si conosce la risposta, sentitevi liberi di aggiungere una risposta a questa domanda: unix.stackexchange.com/questions/551444/... )
— poco tizio

1

Vedi la pagina man di 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)

0

Per quanto riguarda sk_wmem_queuede sk_wmem_alloc, ho fatto la stessa domanda, quindi copierò la risposta qui:

Ho inviato un'e-mail a Eric Dumazet, che contribuisce allo stack di rete Linux, ed ecco la risposta:

sk_wmem_alloctiene traccia del numero di byte per skb in coda dopo lo stack di trasporto: layer qdisc e buffer dell'anello TX NIC.

Se hai 1 MB di dati nella coda di scrittura TCP, non ancora inviati (limite cwnd), sk_wmem_queuesaranno circa 1 MB, ma sk_wmem_allocsaranno circa 0

Un ottimo documento per comprendere quali sono questi tre tipi di code (buffer socket, coda qdisc e coda dispositivo) è questo articolo (piuttosto lungo) . In poche parole, il socket inizia spingendo i pacchetti direttamente sulla coda qdisc, che li inoltra alla coda del dispositivo. Quando la coda qdisc è piena, il socket inizia il buffering dei dati nella propria coda di scrittura.

lo stack di rete posiziona i pacchetti direttamente nella disciplina di accodamento oppure spinge indietro sui livelli superiori (ad es. buffer socket) se la coda è piena

Quindi in sostanza: sk_wmem_queuesè la memoria utilizzata dal buffer del socket (sock.sk_write_queue ) mentre sk_wmem_allocè la memoria utilizzata dai pacchetti nelle qdisc e nelle code dei dispositivi.

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.