Estrutura de soquete do kernel e TCP_DIAG


18

Estou trabalhando em um software que se conecta a um servidor de dados em tempo real (usando TCP) e tenho algumas conexões caindo. Meu palpite é que os clientes não leem os dados provenientes do servidor com rapidez suficiente. Portanto, eu gostaria de monitorar meus soquetes TCP. Para isso, encontrei a ferramenta "ss".

Esta ferramenta permite ver o estado de cada soquete - aqui está um exemplo de linha da saída do 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

Minha pergunta é: o que significa a parte da memória? Analisando o código fonte da ferramenta, descobri que os dados são provenientes de uma estrutura do kernel ( sockin sock.h). Mais precisamente, vem dos campos:

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

Alguém sabe o que eles significam? Minhas suposições são:

  • rmem_alloc : tamanho do buffer de entrada
  • wmem_alloc : tamanho do buffer de saída
  • sk_forward_alloc : ???
  • sk->sk_wmem_queued : ???

Aqui estão os tamanhos dos meus buffers:

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 é a sua configuração de tamanho do buffer? Você vê buffers de recebimento ficando saturados nas conexões de soquete? A sua parte desconecta a conexão no EWOULDBLOCK?
22412 Karlson

Meus tamanhos de soquetes são bem pequenos, eu acho, eu atualizei o post com eles. Para o EWOULDBLOCK, não sei dizer. Meu cliente está em JAVA e apenas digo que foi desconectado pelo servidor. O servidor está em C ++ e apenas diz que ele cancelou a conexão sem nenhuma informação. Eu não tenho o código fonte do servidor, portanto não posso alterar seu comportamento. Parece que os clientes são desconectados quando estão um pouco sobrecarregados, mesmo que durem apenas alguns segundos.
Twister

A configuração dos tamanhos de buffer é ajustável no servidor? Você pode assistir tamanhos de buffer no cliente? Você tem acesso à fonte do cliente? Você já executou o netstat -apnc para observar os tamanhos do buffer? Você tentou aumentar o tamanho do buffer no kernel para ver o que acontece?
314 Karl

Sim, eles são e já estão configurados para o valor máximo do servidor (acredito que eles não podem ser maiores que as propriedades net.ipv4.tcp_ *, certo?) Para netstat -apnc, não me fornece os tamanhos dos buffers, por isso eu olhei para ss. Para o kernel, eu não sou root no servidor e as equipes de TI aqui são bastante teimosas. Preciso ter certeza do que acontece antes de pedir que eles alterem os valores ... E sim, eu tenho acesso à fonte do cliente, e minha investigação no cliente confirma que a desconexão vem do servidor.
Twister

O netstat -apnc fornece o tamanho total das filas de envio e recebimento no Linux. Se o servidor define o buffer para máxima disponível e você ainda está saturando talvez você precise de configurações de buffer mais elevados a nível OS
Karlson

Respostas:


7

sk_forward_alloc é a memória alocada para frente que é a memória total atualmente disponível na cota do soquete.

sk_wmem_queued é a quantidade de memória usada pelo buffer de envio do soquete na fila de transmissão e ainda não foi enviada ou ainda não reconhecida.

Você pode aprender mais sobre o gerenciamento de memória TCP no capítulo 9 da arquitetura, projeto e implementação de TCP / IP no Linux Por Sameer Seth, M. Ajaykumar Venkatesulu


Não entendo como essa definição de sk_wmem_queueddifere sk_wmem_alloc, você poderia expandir um pouco sobre isso? (Se você souber a resposta, sinta-se à vontade para adicionar uma resposta a esta pergunta: unix.stackexchange.com/questions/551444/… )
little-dude

1

Veja a página de manual do 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

Em relação a sk_wmem_queuede sk_wmem_alloc, fiz a mesma pergunta, então copia a resposta aqui:

Enviei um email para Eric Dumazet, que contribui para a pilha de redes Linux, e aqui está a resposta:

sk_wmem_allocrastreia o número de bytes para o skb na fila após a pilha de transporte: camada qdisc e buffers de anel NIC TX.

Se você tiver 1 MB de dados na fila de gravação TCP, ainda não enviados (limite de cwnd), sk_wmem_queueserá de aproximadamente 1 MB, mas sk_wmem_allocserá de aproximadamente 0

Um documento muito bom para entender o que são esses três tipos de filas (buffer de soquete, fila qdisc e fila de dispositivos) é este artigo (bastante longo) . Em poucas palavras, o soquete começa empurrando os pacotes diretamente para a fila qdisc, que os encaminha para a fila do dispositivo. Quando a fila qdisc está cheia, o soquete começa a armazenar em buffer os dados em sua própria fila de gravação.

a pilha de rede coloca pacotes diretamente na disciplina de enfileiramento ou então empurra de volta as camadas superiores (por exemplo, buffer de soquete) se a fila estiver cheia

Então, basicamente: sk_wmem_queuesé a memória usada pelo buffer de soquete ( sock.sk_write_queue) enquanto sk_wmem_allocé a memória usada pelos pacotes nas filas de qdisc e dispositivo.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.