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.