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:
- Onde a memória é relatada? É parte do item
buff/cache
em top
ou é parte da% métrica RES
do processo?
- Se eu quiser reduzi-lo em um nível por processo, como garantir que minhas reduções estejam tendo o efeito desejado?
- 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.
Há 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.