Sistemas Linux em execução prolongada podem desenvolver fragmentação de memória e causar oscilações de desempenho durante alocações de alta ordem. Use os métodos a seguir para reduzir a fragmentação proativamente.
Sintomas
Os serviços na instância apresentam tempos de resposta longos e intermitentes ou picos de latência em chamadas de sistema. O uso da CPU sys aumenta. O buddy system indica escassez de memória de alta ordem (blocos com order > 3). Execute cat /proc/buddyinfo para verificar. A partir da quarta coluna, cada valor exibe a contagem de páginas livres para aquela order:
cat /proc/buddyinfo
Node 0, zone DMA 1 0 0 1 2 1 1 0 1 1 3
Node 0, zone DMA32 3173 856 529 0 0 0 0 0 0 0 0
Node 0, zone Normal 19030 8688 7823 0 0 0 0 0 0 0 0
Causa
Com o tempo, grandes blocos contíguos de memória física se fragmentam em blocos menores não contíguos. Quando um serviço solicita uma alocação grande e contígua, o kernel aciona a compactação de memória. Esse processo lento provoca oscilações de desempenho. Veja abaixo um rastreamento de pilha do kernel típico relacionado à fragmentação:
0xffffffff8118f9cb compaction_alloc ([kernel.kallsyms])
0xffffffff811c88a9 migrate_pages ([kernel.kallsyms])
0xffffffff811901ee compact_zone ([kernel.kallsyms])
0xffffffff8119041b compact_zone_order ([kernel.kallsyms])
0xffffffff81190735 try_to_compact_pages ([kernel.kallsyms])
0xffffffff81631cb4 __alloc_pages_direct_compact ([kernel.kallsyms])
0xffffffff811741d5 __alloc_pages_nodemask ([kernel.kallsyms])
0xffffffff811b5a79 alloc_pages_current ([kernel.kallsyms])
0xffffffff811c0005 new_slab ([kernel.kallsyms])
0xffffffff81633848 __slab_alloc ([kernel.kallsyms])
0xffffffff811c5291 __kmalloc_node_track_caller ([kernel.kallsyms])
0xffffffff8151a8c1 __kmalloc_reserve.isra.30 ([kernel.kallsyms])
0xffffffff8151b7cd alloc_sib ([kernel.kallsyms])
0xffffffff815779e9 sk_stream_alloc_skb ([kernel.kallsyms])
0xffffffff8157872d tcp_sendmsg ([kernel.kallsyms])
0xffffffff815a26b4 inet_sendmsg ([kernel.kallsyms])
0xffffffff81511017 sock_aio_write ([kernel.kallsyms])
0xffffffff811df729 do_sync_readv_writev ([kernel.kallsyms])
0xffffffff811e0cfe do_readv_writev ([kernel.kallsyms])
Soluções
use os métodos abaixo para mitigar a fragmentação de memória:
-
Ajuste o watermark mínimo
Defina o watermark mínimo entre 1% e 3% da memória total (recomenda-se 2%). Essa configuração aciona a recuperação assíncrona mais cedo quando há pouca memória livre. Execute:
sysctl -w vm.min_free_kbytes = memtotal_kbytes * 2%Substitua
memtotal_kbytes * 2%por 2% da memória total da sua instância em KB. -
Ajuste a diferença entre os watermarks mínimo e baixo
O parâmetro de kernel
watermark_scale_factorcontrola a diferença entre os watermarks mínimo e baixo para ajudar a absorver alocações em rajada. A diferença padrão é de 0,1% da memória total, e o mínimo corresponde à metade do watermark mínimo. Para ajustar owatermark_scale_factor, execute:sysctl -w vm.watermark_scale_factor = valueO
valueé um fator de escala que ajusta a diferença entre omin watermarke olow watermark. -
Compacte a memória periodicamente
Em horários de menor demanda, acione manualmente a
memory compactionassíncrona:echo 1 > /proc/sys/vm/compact_memory -
Limpe o cache periodicamente
Se os métodos anteriores forem insuficientes, limpe o cache durante uma janela de manutenção planejada. Essa ação libera páginas de memória para realocação e reduz a fragmentação, mas causa oscilações temporárias de desempenho. Execute:
echo 3 > /proc/sys/vm/drop_caches