Como saber quantos buffers TCP de memória estão realmente usando?

4

Eu tenho uma máquina front-end com cerca de 1k de conexões TCP persistentes e com largura de banda muito baixa. É um pouco de memória restrita, então estou tentando descobrir onde algumas centenas de MBs estão indo. Buffers TCP são um dos possíveis culpados, mas não posso me importar com essas questões:

  1. Onde a memória é relatada? É parte do item buff/cache em top ou é parte da% métrica RES do processo?
  2. Se eu quiser reduzi-lo em um nível por processo, como garantir que minhas reduções estejam tendo o efeito desejado?
  3. Os buffers continuam a ocupar alguma memória mesmo quando há tráfego mínimo ou eles crescem dinamicamente, com o tamanho do buffer sendo apenas o tamanho máximo permitido?

Eu percebo que uma possível resposta é "confiar no kernel para fazer isso por você", mas eu quero descartar buffers TCP como uma fonte de pressão de memória.

Investigação: Questão 1

Esta página escreve:" a memória dos 'buffers' é a memória usada pelo Linux para armazenar em buffer as conexões de rede e de disco. " Isso significa que eles não fazem parte da RES métrica em top .

Para encontrar o uso de memória real, /proc/net/sockstat é o mais promissor:

sockets: used 3640
TCP: inuse 48 orphan 49 tw 63 alloc 2620 mem 248
UDP: inuse 6 mem 10
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0

Isso é a melhor explicação que pude encontrar, mas mem não é abordado lá. Ele é endereçado aqui , mas 248 * 4k ~ = 1MB, ou cerca de 1/1000 o máximo do sistema, o que parece ser um número absurdamente baixo para um servidor com centenas de conexões persistentes e tráfego de rede sustentado de 0,2 a 0,3Mbps. >

É claro que os limites de memória do sistema são:

$ grep . /proc/sys/net/ipv4/tcp*mem
/proc/sys/net/ipv4/tcp_mem:140631   187510  281262
/proc/sys/net/ipv4/tcp_rmem:4096    87380   6291456
/proc/sys/net/ipv4/tcp_wmem:4096    16384   4194304
O terceiro parâmetro do

tcp_mem é o número máximo de páginas dedicadas a buffers TCP em todo o sistema; se o total do tamanho do buffer ultrapassar esse valor, o kernel começará a descartar pacotes. Para cargas de trabalho não exóticas, não há necessidade de ajustar este valor.

A próxima atualização é /proc/meminfo e seus itens misteriosos Buffers e Cached . Eu olhei para várias fontes, mas não consegui encontrar nenhuma que alegasse ser responsável por buffers TCP.

...
MemAvailable:    8298852 kB
Buffers:          192440 kB
Cached:          2094680 kB
SwapCached:        34560 kB
...

Investigação: Perguntas 2-3

Para inspecionar os tamanhos de buffer de TCP no nível do processo, temos algumas opções, mas nenhuma delas parece fornecer a memória real alocada em vez do tamanho da fila atual ou o máximo.

ss -m --info :

State       Recv-Q Send-Q
ESTAB       0      0
... <snip> ....
skmem:(r0,rb1062000,t0,tb2626560,f0,w0,o0,bl0)  ...<snip> rcv_space:43690

Então nós temos

  • Recv-Q e Send-Q , o uso atual do buffer
  • r e t , que são explicados em este excelente post , mas não está claro como eles são diferentes de Recv-Q e Send-Q
  • Algo chamado rb , que parece suspeitamente com algum tipo de tamanho máximo do buffer, mas para o qual não consegui encontrar nenhuma documentação
  • rcv_space , que esta página não é o tamanho real do buffer; para isso você precisa chamar getsockopt

Esta resposta sugere lsof , mas o tamanho / off parece estar relatando o mesmo uso do buffer que ss :

COMMAND     PID   TID                USER   FD      TYPE             DEVICE SIZE/OFF       NODE NAME
sslocal    4032                   michael   82u     IPv4            1733921      0t0        TCP localhost:socks->localhost:59594 (ESTABLISHED)

E depois estas respostas sugerem que lsof não pode retornar o tamanho real do buffer. Ele fornece um módulo do kernel que deve fazer o truque, mas parece funcionar em soquetes cujos tamanhos de buffer foram corrigidos com setsockopt ; se não, SO_SNDBUF e SO_RCVBUF não estão incluídos.

    
por Mike Fischer 25.01.2018 / 05:05

2 respostas

3

/proc/net/sockstat , especificamente o campo mem , é onde procurar. Este valor é relatado nas páginas do kernel e corresponde diretamente a /proc/sys/net/ipv4/tcp_mem .

No nível do soquete individual, a memória é alocada no espaço do kernel apenas até que o código do espaço do usuário a leia, momento em que a memória do kernel é liberada (consulte aqui ). sk_buff->truesize é a soma tanto da quantidade de dados armazenados em buffer, quanto da própria estrutura de soquete (consulte aqui , e o patch que corrige o alinhamento de memória é falado sobre aqui )

Eu suspeito que o campo mem de /proc/net/sockstat é calculado simplesmente pela soma de sk_buff->truesize para todos os sockets, mas não estou familiarizado o suficiente com a origem do kernel para saber onde procurar isso.

Por meio de confirmação, esta solicitação de recurso do sistema de monitoramento netdata inclui muita discussão e comentários relevantes links também, e faz o backup desta interpretação de /proc/net/sockstat .

Este post no erro "out of socket memory" contém alguns discussão mais geral de diferentes problemas de memória.

    
por 26.01.2018 / 10:22
2

Esta é uma questão muito complexa que pode requerer um aprofundamento na fonte do kernel para encontrar uma resposta.

Não parece que o buffer esteja incluído na estatística RES do processo. Veja este artigo (se você tiver já está). Segundo o autor:

device drivers allocate a region of memory for the device to perform DMA to incoming packets

Mais abaixo, na seção "Ajuste: Memória da fila de recebimento do soquete", parece que net.core.wmem_max e net.core.rmem_max são os tamanhos máximos do buffer. Novamente, não tenho certeza de como ver realmente quanta memória está sendo usada.

Aparentemente, dentro da pilha de rede há um problema com documentação deficiente e, obviamente, uma grande quantidade de complexidade. Aqui está o

Além disso, quanto mais eu leio sobre o modo como o buffering é tratado, não parece que o kernel vanilla suporta a visualização de algo que não seja a quantidade de memória alocada como um buffer.

Este bit de documentação sobre O DMA dentro do kernel também pode ser útil para você, ou pelo menos lhe dar uma idéia de onde você pode ir a partir daqui, mas por enquanto eu acho que o módulo do kernel fornecido é o mais próximo que você pode obter.

    
por 25.01.2018 / 06:32

Tags