Restringir o tamanho do cache de buffer no Linux

15

Existe uma maneira de dizer ao kernel do Linux para usar apenas uma certa porcentagem de memória para o cache de buffer? Eu sei que /proc/sys/vm/drop_caches pode ser usado para limpar o cache temporariamente, mas existe alguma configuração permanente que impeça que ele cresça mais do que, por exemplo, 50% da memória principal?

A razão pela qual eu quero fazer isso é que eu tenho um servidor rodando um Ceph OSD que constantemente serve dados do disco e consegue usar toda a memória física como cache de buffer dentro de algumas horas. Ao mesmo tempo, eu preciso executar aplicativos que irão alocar uma grande quantidade (vários 10s de GB) de memória física. Ao contrário da crença popular (veja o conselho dado em quase todas as questões relativas ao cache de buffer), a liberação automática da memória descartando entradas de cache limpas é não instantânea: iniciar meu aplicativo pode levar até um minuto quando o cache de buffer está cheio (*), enquanto após limpar o cache (usando echo 3 > /proc/sys/vm/drop_caches ) o mesmo aplicativo é iniciado quase instantaneamente.

(*) Durante este minuto do tempo de inicialização, o aplicativo está com falha na nova memória, mas gasta 100% de seu tempo no kernel, de acordo com o Vtune, em uma função chamada pageblock_pfn_to_page . Essa função parece estar relacionada à compactação de memória necessária para encontrar páginas enormes, o que me leva a acreditar que, na verdade, a fragmentação é o problema.

    
por Wim 07.01.2016 / 10:54

5 respostas

9

Se você não quiser um limite absoluto, mas apenas pressionar o kernel para liberar os buffers mais rapidamente, você deve olhar para vm.vfs_cache_pressure

This variable controls the tendency of the kernel to reclaim the memory which is used for caching of VFS caches, versus pagecache and swap. Increasing this value increases the rate at which VFS caches are reclaimed.

Varia de 0 a 200. Mova-o para 200 para maior pressão. O padrão é definido como 100. Você também pode analisar o uso da memória usando o comando slabtop . No seu caso, os valores de dentry e *_inode_cache devem ser altos.

Se você quiser um limite absoluto, deverá procurar cgroups . Coloque o servidor Ceph OSD dentro de um cgroup e limite a memória máxima que pode usar configurando o parâmetro memory.limit_in_bytes para o cgroup.

memory.memsw.limit_in_bytes sets the maximum amount for the sum of memory and swap usage. If no units are specified, the value is interpreted as bytes. However, it is possible to use suffixes to represent larger units — k or K for kilobytes, m or M for Megabytes, and g or G for Gigabytes.

Referências:

[1] - Ajuste do kernel do GlusterFS Linux

[2] - RHEL 6 Guia de gerenciamento de recursos

    
por 13.01.2016 / 04:18
3

Eu não sei sobre A%, mas você pode definir um limite de tempo para que ele seja descartado após x quantidade de minutos.

Primeiro em um terminal

sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

Para limpar os caches atuais.

Faça um cron-job Pressione Alt-F2, digite gksudo gedit /etc/crontab , e adicione essa linha na parte inferior.

 */15 *    * * *   root    sync && echo 3 > /proc/sys/vm/drop_caches

Isso limpa a cada 15 minutos. Você pode definir a 1 ou 5 minutos, se você realmente quiser, alterando o primeiro parâmetro para * ou * / 5 em vez de * / 15

Para ver sua RAM livre, exceto o cache:

free -m | sed -n -e '3p' | grep -Po "\d+$
    
por 13.01.2016 / 01:35
1

tuned é um daemon de ajuste dinâmico do sistema adaptativo que ajusta as configurações do sistema dinamicamente dependendo do uso.

 $ man tuned

Consulte a documentação relacionada e os arquivos de configuração.

 /etc/tuned
 /etc/tuned/*.conf
 /usr/share/doc/tuned-2.4.1
 /usr/share/doc/tuned-2.4.1/TIPS.txt

This parameter may be useful for you.

** Set flushing to once per 5 minutes
** echo "3000" > /proc/sys/vm/dirty_writeback_centisecs

Informações adicionais

O comando sync libera o buffer, ou seja, força todos os dados não gravados a serem gravados no disco e pode ser usado quando se deseja ter certeza de que tudo está gravado com segurança. Nos sistemas UNIX tradicionais, há um programa chamado update sendo executado em segundo plano que faz uma sincronização a cada 30 segundos, portanto, geralmente não é necessário usar a sincronização. O Linux tem um daemon adicional, bdflush , que faz uma sincronização mais imperfeita com mais frequência para evitar o congelamento repentino devido a E / S pesada de disco que a sincronização causa.

No Linux, o bdflush é iniciado pela atualização. Normalmente não há razão para se preocupar, mas se o bdflush morrer por algum motivo, o kernel irá avisar sobre isso, e você deve iniciá-lo manualmente ( / sbin / update ).

    
por 07.01.2016 / 11:18
1

Acho que seu palpite no final de sua pergunta está no caminho certo. Eu suspeito que a alocação de memória A, compatível com NUMA, que migra páginas entre CPUs, ou B, mais provavelmente, o código de desfragmentação de páginas amplas transparentes tentando encontrar regiões alinhadas e contíguas.

Hugepages e hugepages transparentes foram identificados para melhorias de desempenho marcantes em determinadas cargas de trabalho e responsáveis por consumir enormes quantidades de tempo de CPU sem fornecer muitos benefícios.

Ajudaria a saber qual kernel você está executando, o conteúdo de / proc / meminfo (ou pelo menos os valores de HugePages_ *.) e, se possível, mais referências de callgraph de profiler vtune pageblock_pfn_to_page ().

Além disso, se você aceitar meu palpite, tente desativar a desfragmentação da hugepage com:

echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag

(pode ser isso em vez disso, dependendo do seu kernel:)

echo 'never' > /sys/kernel/mm/redhat_transparent_hugepage/defrag

Por fim, esse aplicativo usa muitas dezenas de shows de ram que você escreveu? Que língua?

Desde que você usou o termo "falhas nas páginas de memória", acredito que você esteja familiarizado o suficiente com o design operacional e a memória virtual. Eu me esforço para imaginar uma situação / aplicativo que estaria falhando de forma tão agressiva que não esteja sendo lida em muitas E / S - quase sempre do cache de buffer que você está tentando limitar.

(Se você está curioso, confira os flags mmap (2) como MAP_ANONYMOUS e MAP_POPULATE e mincore (2) que podem ser usados para ver quais páginas virtuais realmente têm uma página física mapeada.)

Boa sorte!

    
por 16.01.2016 / 17:35
1

Se o Ceph OSD for um processo separado, você pode usar cgroups para controlar recursos utilizados pelo processo:

Crie um cgroup chamado like group1 com um limite de memória (de 50GB, por exemplo, outros limites como CPU são suportados, no exemplo CPU também é mencionado):

cgcreate -g memory,cpu:group1

cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1

Em seguida, se o aplicativo já estiver em execução, leve o aplicativo para este cgroup:

cgclassify -g memory,cpu:group1 $(pidof your_app_name)

Ou execute seu aplicativo neste cgroup:

cgexec -g memory,cpu:group1 your_app_name
    
por 16.03.2018 / 13:39