Troca permanente com muita memória livre

5

Nós temos um servidor Linux rodando o Debian 4.0.5 (Kernel 4.0.0-2) com 32G RAM instalado e o 16G Swap configurado. O sistema usa recipientes lxc para compartimentalização, mas isso não importa aqui. O problema existe dentro e fora de contêineres diferentes.

Veja um típico free -h :

              total        used        free      shared  buff/cache   available
Mem:            28G        2.1G         25G         15M        936M         26G
Swap:           15G        1.4G         14G

/proc/meminfo tem

Committed_AS:   12951172 kB

Portanto, há bastante memória livre, mesmo que tudo que foi alocado tenha sido usado ao mesmo tempo. No entanto, o sistema está paginando instantaneamente até mesmo processos em execução.

Isso é mais notável com o Gitlab, um aplicativo Rails usando Unicorn: trabalhadores recém-unificados são instantaneamente trocados e quando um pedido precisa ser lido do disco em ~ 1400kB / s (dados de iotop ) e é executado em timeouts (30s por enquanto, para reiniciá-lo a tempo. Nenhum pedido normal deve levar mais que 5s) antes de ser carregado na memória completamente, sendo assim morto instantaneamente. Note que este é apenas um exemplo, eu vi isso acontecer com o redis, o amavis, o postgres, o mysql, o java (openjdk) e outros.

O sistema está em uma situação de baixa carga com cerca de 5% de utilização da CPU e um loadavg em torno de 2 (em 8 núcleos).

O que tentamos (sem uma ordem específica):

  1. swapoff -a : falha em cerca de 800M ainda trocado
  2. Reduzindo o swappiness (em etapas) usando sysctl vm.swappiness=NN . Isso parece não ter nenhum impacto, descemos para 0% e ainda existe exatamente o mesmo comportamento
  3. Interrompendo serviços não essenciais (Gitlab, um aplicativo da Web baseado no Jetty), liberando ca. 8G de memória confirmada mas não mapeada e reduzindo o Committed_AS para cerca de 5G. Nenhuma mudança em tudo.
  4. Limpando caches do sistema usando sync && echo 3 > /proc/sys/vm/drop_caches . Isso libera a memória, mas não faz nada para a situação de troca.
  5. Combinações do acima

Reiniciar a máquina para desabilitar completamente o swap via fstab como um teste não é realmente uma opção, já que alguns serviços têm problemas de disponibilidade e precisam de downtime planejados, não "bisbilhotando" ... e também não queremos desabilitar trocar como fallback.

Não vejo por que há alguma troca ocorrendo aqui. Alguma idéia do que pode estar acontecendo?

Este problema já existe há algum tempo, mas apareceu primeiro durante um período de alta carga de I / O (longa tarefa de processamento de dados em segundo plano), portanto não consigo identificar um evento específico. Esta tarefa é feita durante alguns dias e o problema persiste, daí a questão.

    
por Martok 23.08.2015 / 18:31

1 resposta

6

Lembre-se de como eu disse:

The system uses lxc containers for compartmentalisation, but that shouldn't matter here.

Bem, acontece que o importava. Ou melhor, os cgroups no coração da matéria lxc.

A máquina host só vê reinicializações para atualizações de kernel. Então, quais foram os últimos kernels usados? 3.19, substituído por 4.0.5 há 2 meses e ontem com 4.1.3. E o que aconteceu ontem? Processos ficando memk esquerda, direita e centro. Verificando /var/log/kern.log , os processos afetados estavam em cgroups com 512M de memória. Espere, 512 milhões? Isso não pode estar certo (quando o requisito esperado é de cerca de 4G!). Acontece que isso é exatamente o que configuramos nas configurações do lxc quando configuramos tudo isso meses atrás.

Então, o que aconteceu é que 3,19 ignorou completamente o limite de memória para cgroups; 4.0.5 sempre paginado se o cgroup exigia mais do que o permitido (esta é a questão central desta questão) e somente o 4.1.3 faz um full memkiller-sweep.

O swappiness do sistema host não teve influência sobre isso, já que nunca esteve perto de estar fora da memória física.

A solução:

Para uma alteração temporária, você pode modificar diretamente o cgroup, por exemplo, para um contêiner lxc chamado box1 o cgroup é chamado lxc/box1 e você pode executar (como root na máquina host):

$ echo 8G > /sys/fs/cgroup/memory/lxc/box1/memory.limit_in_bytes

A solução permanente é configurar corretamente o contêiner em /var/lb/lxc/...

lxc.cgroup.memory.limit_in_bytes = 8G

Moral da história: sempre verifique sua configuração. Mesmo se você acha que não pode ser o problema (e leva um erro / inconsistência diferente no kernel para realmente falhar).

    
por 26.08.2015 / 21:52