O que é VM.min_free_kbytes e como ajustá -lo?

O que é VM.min_free_kbytes e como ajustá -lo?
O que é VM.min_free_kbytes sysctl sintonizável para kernel Linux e que valor deve ser definido como? Estudaremos este parâmetro e como isso afeta um sistema Linux em execução neste artigo. Testaremos seu impacto no cache da página do sistema operacional e nos mallocs e o que o comando grátis do sistema mostra quando este parâmetro é definido. Faremos algumas suposições educadas sobre os valores ideais para este ajustável e mostraremos como definir a VM.min_free_kbytes permanentemente para sobreviver às reinicializações. Então vamos.

Como vm.min_free_kbytes funciona

Alocações de memória podem ser necessárias pelo sistema para garantir o funcionamento adequado do próprio sistema. Se o kernel permitir que toda a memória seja alocada, ela poderá lutar ao precisar de memória para operações regulares para manter o sistema operacional funcionando sem problemas. É por isso que o kernel fornece a VM ajustável.min_free_kbytes. O ajustável forçará o gerente de memória do kernel a manter pelo menos x quantidade de memória livre. Aqui está a definição oficial da documentação do kernel Linux: “Isso é usado para forçar a VM Linux para manter um número mínimo de kilobytes grátis. A VM usa esse número para calcular um valor de marca d'água [wmark_min] para cada zona Lowmem no sistema. Cada zona lowmem recebe uma série de páginas livres reservadas baseadas proporcionalmente em seu tamanho. É necessária alguma quantidade mínima de memória para satisfazer as alocações PF_MEMALLOC; Se você definir isso para menos de 1024kb, seu sistema ficará sutilmente quebrado e propenso a deadlock sob cargas altas. Definir isso muito alto vai para sua máquina instantaneamente.““

Validando VM.min_free_kbytes funciona

Para testar que a configuração de min_free_kbytes está funcionando como projetado, criei uma instância virtual do Linux com apenas 3.75 GB de RAM. Use o comando gratuito abaixo para analisar o sistema:

# grátis -m

Olhando para o utilitário de memória livre acima usando o sinalizador -m para ter os valores impressos em MB. A memória total é 3.5 a 3.75 GB de memória. 121 MB de memória é usado, 3.3 GB de memória é gratuito, 251 MB é usado pelo cache do buffer. E 3.3 GB de memória está disponível.

Agora vamos mudar o valor da VM.min_free_kbytes e veja qual é o impacto na memória do sistema. Vamos ecoar o novo valor ao sistema de arquivos Virtual Proc para alterar o valor do parâmetro do kernel conforme abaixo:

# echo 1500000>/proc/sys/vm/min_free_kbytes
# sysctl vm.min_free_kbytes

Você pode ver que o parâmetro foi alterado para 1.5 GB aproximadamente e entrou em vigor. Agora vamos usar o livre comando novamente para ver quaisquer alterações reconhecidas pelo sistema.

# grátis -m

A memória livre e o cache do buffer permanecem inalterados pelo comando, mas a quantidade de memória exibida como disponível foi reduzido de 3327 para 1222 MB. Que é uma redução aproximada da mudança no parâmetro para 1.Memória livre de 5 GB min.

Agora vamos criar um arquivo de dados de 2 GB e depois ver o que lendo esse arquivo no cache do buffer faz com os valores. Aqui está como criar um arquivo de dados de 2 GB em 2 linhas de script Bash abaixo. O script gerará um arquivo aleatório de 35 MB usando o comando dd e depois copiará 70 vezes em um novo data_file saída:

# dd if =/dev/aleatório de =/root/d1.contagem txt = 1000000
# para i na 'seq 1 70'; eco $ i; gato /raiz /d1.txt >> /root /data_file; feito

Vamos ler o arquivo e ignorar o conteúdo lendo e redirecionando o arquivo para /dev /null conforme abaixo:

# CAT data_file> /dev /null

Ok, o que aconteceu com a memória do sistema com este conjunto de manobras, vamos verificar agora:

# grátis -m

Analisando os resultados acima. Nós ainda temos 1.8 GB de memória livre para que o kernel protegesse um grande pedaço de memória como reservado por causa de nossa configuração min_free_kbytes. O cache do buffer usou 1691 Mb, que é menor que o tamanho total do nosso arquivo de dados, que é 2.3 GB. Aparentemente o todo data_file Não foi possível armazenado em cache devido à falta de memória disponível para usar no cache do buffer. Podemos validar que todo o arquivo não é armazenado em cache, mas cronometrando as repetidas tentativas de ler o arquivo. Se fosse em cache, levaria uma fração de segundo para ler o arquivo. Vamos tentar.

# time gat data_file> /dev /null
# time gat data_file> /dev /null

A leitura do arquivo levou quase 20 segundos, o que implica que quase certamente nem todos os cache.

Como uma validação final, vamos reduzir a VM.min_free_kbytes para permitir que o cache da página tenha mais espaço para operar e podemos esperar ver o cache funcionando e a leitura do arquivo ficando muito mais rápido.

# echo 67584>/proc/sys/vm/min_free_kbytes
# time gat data_file> /dev /null
# time gat data_file> /dev /null

Com a memória extra disponível para armazenar em cache o tempo de leitura do arquivo caiu de 20 segundos antes para .364 segundos com tudo em cache.

Estou curioso para fazer outro experimento. O que acontece com as chamadas de Malloc para alocar memória de um programa C diante desta VM realmente alta.Configuração min_free_kbytes. Isso falhará o malloc? O sistema morrerá? Primeiro redefinir a vm.min_free_kbytes configurando o valor realmente alto para retomar nossos experimentos:

# echo 1500000>/proc/sys/vm/min_free_kbytes

Vamos olhar novamente para a nossa memória livre:

Teoricamente, temos 1.9 GB livre e 515 MB disponíveis. Vamos usar um programa de teste de estresse chamado Stress-NG para usar alguma memória e ver onde falhamos. Usaremos o testador da VM e tentaremos alocar 1 GB de memória. Desde que apenas reservamos 1.5 GB em um 3.Sistema de 75 GB, acho que isso deve funcionar.

# estresse-ng --vm 1 --vm-bytes 1g-timeout 60s
Estresse-NG: Info: [17537] Despacha porcos: 1 VM
Estresse-NG: Info: [17537] ALROCAR CACHE: Tamanho do cache padrão: 46080K
estresse-ng: informações: [17537] Execução bem-sucedida concluída em 60.09s (1 min, 0.09 Secs)
# estresse-ng --vm 2 --vm-bytes 1g-timeout 60s
# estresse-ng --vm 3 --vm-bytes 1g-timeout 60s

Vamos tentar novamente com mais trabalhadores, podemos tentar 1, 2, 3, 4 trabalhadores e, em algum momento, deve falhar. No meu teste, ele passou com 1 e 2 trabalhadores, mas falhou com 3 trabalhadores.

Vamos redefinir a VM.min_free_kbytes para um número baixo e veja se isso nos ajuda a executar 3 estressores de memória com 1 GB cada um em um 3.Sistema de 75 GB.

# echo 67584>/proc/sys/vm/min_free_kbytes
# estresse-ng --vm 3 --vm-bytes 1g-timeout 60s

Desta vez, funcionou com sucesso sem erro, tentei duas vezes sem problemas. Para que eu possa concluir que há uma diferença comportamental de ter mais memória disponível para Malloc, quando a VM.min_free_kbytes o valor é definido como um valor mais baixo.

Configuração padrão para VM.min_free_kbytes

O valor padrão para a configuração no meu sistema é 67584, que é cerca de 1.8% da RAM no sistema ou 64 MB. Por razões de segurança em um sistema fortemente espancado, eu tenderia a aumentá -lo um pouco para 128 MB para permitir uma memória livre mais reservada, no entanto, para uso médio, o valor padrão parece sensato o suficiente. A documentação oficial alerta sobre tornar o valor muito alto. Definê -lo para 5 ou 10% da RAM do sistema provavelmente não é o uso pretendido da configuração e é muito alto.

Definindo vm.min_free_kbytes para sobreviver às reinicializações

Para garantir que a configuração possa sobreviver às reinicializações e não é restaurada aos valores padrão ao reiniciar, certifique -se de tornar a configuração SYSCTL persistente ao colocar o novo valor desejado no /etc /sysctl.arquivo conf.

Conclusão

Vimos que a VM.min_free_kbytes linux kernel ajustável pode ser modificado e pode reservar memória no sistema para garantir que o sistema seja mais estável, especialmente durante o uso pesado e alocações de memória pesada. As configurações padrão podem ser um pouco baixas demais, especialmente em sistemas de memória alta e devem ser consideradas aumentadas cuidadosamente. Vimos que a memória reservada por este ajustável impede que o cache do sistema operacional use toda a memória e também impede que algumas operações mallocas também usem toda a memória.