Restringir o tamanho do cache do buffer no Linux

25

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

A razão pela qual desejo fazer isso é que tenho um servidor executando um Ceph OSD que constantemente fornece dados do disco e consegue usar toda a memória física como cache de buffer dentro de algumas horas. Ao mesmo tempo, preciso executar aplicativos que aloquem uma grande quantidade (vários 10s de GB) de memória física. Ao contrário da crença popular (consulte os conselhos de quase todas as perguntas relacionadas ao cache do buffer), a liberação automática da memória descartando entradas limpas do cache não é instantânea: iniciar meu aplicativo pode levar até um minuto quando o cache do buffer estiver cheio ( *), depois de limpar o cache (usando echo 3 > /proc/sys/vm/drop_caches) o mesmo aplicativo inicia quase instantaneamente.

(*) Durante esse minuto de 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 realmente a fragmentação é o problema.

Wim
fonte
11
Há algo chamado classificação por cache. conjunto de conjuntos ceph osd {cachepool} hit_set_count 1 conjunto de conjuntos ceph osd {cachepool} hit_set_period 3600 conjunto de conjuntos ceph osd {cachepool} target_max_bytes 1000000000000 como exemplo. docs.ceph.com/docs/master/rados/operations/cache-tiering
Michael D.
2
Como esse problema aparentemente afeta apenas a inicialização dos aplicativos com uso intenso de memória, talvez você possa iniciar os aplicativos por meio de um script que limpa o cache antes de realmente iniciá-los. Talvez isso os inicie mais rapidamente, deixando o gerenciamento de cache para o kernel enquanto eles estão em execução.
Thawn 15/01/16

Respostas:

14

Se você não deseja um limite absoluto, mas apenas pressiona o kernel para liberar os buffers mais rapidamente, consulte vm.vfs_cache_pressure

Essa variável controla a tendência do kernel de recuperar a memória usada para armazenar em cache os caches do VFS, versus pagecache e swap. Aumentar esse valor aumenta a taxa na qual os caches do VFS são recuperados.

Varia de 0 a 200. Mova-o para 200 para aumentar a pressão. O padrão é definido como 100. Você também pode analisar o uso da memória usando o slabtopcomando No seu caso, os valores dentrye *_inode_cachedevem ser altos.

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

memory.memsw.limit_in_bytesdefine a quantidade máxima para a soma de memória e uso de swap. Se nenhuma unidade for especificada, o valor será interpretado como bytes. No entanto, é possível usar sufixos para representar unidades maiores - k ou K para kilobytes, m ou M para megabytes e g ou G para gigabytes.

Referências:

[1] - Ajuste do kernel do GlusterFS Linux

[2] - Guia de Gerenciamento de Recursos RHEL 6

NOLFXceptMe
fonte
11
Um cgroup com limit_in_bytesset parece fazer isso. Obrigado!
Wim
4
Eu acho que vfs_cache_pressureapenas limpa caches de dentry e inode, e não tem nada a ver com cache de buffer.
Kawing-chiu
Aumentar vfs_cache_pressureacima 100pode ajudar caso você não tenha RAM suficiente para sua carga de trabalho. Reduzirá o uso da RAM, mas causará um desempenho geral de E / S inferior.
Mikko Rantalainen
3

Não sei sobre A%, mas você pode definir um limite de tempo para que ele caia após x minutos.

Primeiro em um terminal

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

Para limpar caches atuais.

Torne-o um cron-job Pressione Alt-F2, digite gksudo gedit /etc/crontab, Em seguida , adicione esta linha perto da parte inferior.

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

Isso limpa a cada 15 minutos. Você pode definir para 1 ou 5 minutos, se realmente desejar, 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+$
DnrDevil
fonte
Sinto aqui um pouco de redundância. Até onde eu sei, isso 3 > drop_cachesinclui o comportamento desync
andras.tim 6/17
11
@ andras.tim no - sync grava páginas sujas no disco, 3 para drop_caches apenas recupera / libera memória usada por páginas limpas e outros caches. você não tem que correr sincronização, mas se o fizer, mais memória será limpo em vez de sujo e mais memória será liberada quando você deixa cair caches
Daniel S. Sterling
2

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

Páginas enormes e páginas enormes transparentes foram identificadas para melhorias de desempenho marcantes em determinadas cargas de trabalho e responsáveis ​​por consumir enormes quantidades de tempo da CPU sem fornecer muitos benefícios.

Seria útil saber em qual kernel você está executando, o conteúdo de / proc / meminfo (ou pelo menos os valores HugePages_ *.) E, se possível, mais informações sobre o calltraph do gerador de perfil vtune referenciando pageblock_pfn_to_page ().

Além disso, se você concordar com o meu palpite, tente desativar o Hugepage desfragmentar com:

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

(pode ser isso, dependendo do seu kernel :)

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

Por fim, este aplicativo está usando muitas dezenas de shows de RAM algo que você escreveu? Que lingua?

Desde que você usou o termo "falha nas páginas de memória", suponho que você esteja familiarizado o suficiente com design operacional e memória virtual. Eu luto para imaginar uma situação / aplicativo que falharia de forma tão agressiva que não esteja lendo muitas E / S - quase sempre do cache do buffer que você está tentando limitar.

(Se você estiver curioso, confira sinalizadores 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!

etherfish
fonte
2

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

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

cgcreate -g memory,cpu:group1

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

Então, 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 dentro deste cgroup:

cgexec -g memory,cpu:group1 your_app_name
Alexei Martianov
fonte
0

sintonizado é um daemon de ajuste do sistema adaptativo dinâmico 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ção adicional

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 quer ter certeza de que tudo está gravado com segurança. Nos sistemas UNIX tradicionais, há um programa chamado update em execução em segundo plano, que faz uma sincronização a cada 30 segundos; portanto, geralmente não é necessário usar a sincronização. O Linux possui um daemon adicional, bdflush , que faz uma sincronização mais imperfeita com mais frequência para evitar o congelamento repentino devido à E / S de disco pesada que sincronização às vezes causa.

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

Ijaz Ahmad Khan
fonte
11
Isso não é apenas para entradas sujas? Eu não acho que esse seja o problema no meu sistema, pois todos estão limpos - o atraso não está em escrever páginas sujas, mas em desfragmentar o espaço deixado pela remoção de páginas limpas.
Wim
Sim, isso é para páginas sujas, acho que você também pode corrigir outros problemas de desempenho configurando o modo dinâmico.
Ijaz Ahmad Khan
"Desde o Linux 2.6, a chamada de sistema [bdflush] está obsoleta e não faz nada. É provável que desapareça completamente em uma versão futura do kernel. Atualmente, a tarefa executada por bdflush () é tratada pelo thread pdflush do kernel." man7.org/linux/man-pages/man2/bdflush.2.html
sourcejedi