Ferramenta para forçar o uso de FILE em vez de RAM

3

Estou me perguntando por que não existe essa ferramenta como ram2swap , semelhante a cpulimit em partes.

Por exemplo,

Existe o programa daemon.bin.

Vamos criar um arquivo de troca temporário (1 Gb):

% dd if=/dev/zero of=tmp.swap bs=1m count=1000

Lançamento:

% cpulimit -l 10 ram2swap -f tmp.swap daemon.bin

Em vez de uso de RAM ou SWAP, o daemon.bin alocará memória no arquivo tmp.swap .

Reduza drasticamente o desempenho, sim. Mas como isso é flexível.

    
por Anomalous Awe 15.04.2014 / 15:47

2 respostas

4

Não existe essa ferramenta porque não faz sentido do ponto de vista de um único programa.

Pode-se considerar CPU / HDD / RAM / swap como recursos. Esses recursos podem ser compartilhados de diferentes maneiras pelo sistema operacional entre processos, usuários, contextos, etc.

Em algumas situações específicas, faz sentido dizer ao sistema operacional para impor limites rígidos:

  • Não permita que este programa use mais de 60% da memória.
  • Não permita que este usuário use mais de 20% do tempo da CPU se outro usuário precisar. Outra coisa permite que ele use 100% da CPU.
  • Não permita que usuários desse grupo usem mais de dois núcleos.
  • ...

Isso fornece uma flexibilidade real: os recursos são compartilhados entre os usuários de acordo com os desejos do administrador e o SO está em conformidade.

Por que colocar manualmente um programa para trocar não é uma boa ideia?

  • Você está basicamente assumindo que é melhor que a heurística no kernel. O kernel já lida com o espaço de troca sozinho. Se um daemon não tiver sido ativado por um longo tempo e o SO não tiver memória RAM, ele eventualmente será colocado em swap.
  • AFAIK, swap não é executável: antes de ser executado, o conteúdo do swap precisa ser recuperado na RAM. Então, se você estava pensando em programas de primeira classe sendo executados a partir da RAM e programas de segunda classe sendo executados a partir de swap: pare agora, isso não funcionará.
  • "Sim, mas esse daemon específico é chamado duas vezes por mês. Eu não preciso disso na RAM". Se for verdade, o kernel irá colocar em swap se você não tiver RAM.
  • "Por que esperar pela falta de RAM?" Colocar as coisas dentro e fora da troca é muito caro, especialmente em HDD antigo. Se o seu sistema puder manter tudo na RAM, é melhor deixá-lo fazer isso. Se você forçar algo na troca, por enquanto, seu sistema será menos responsivo. Já que seus outros daemons de "1ª classe" provavelmente também farão algumas IO de HDD, eles também serão retardados. A mesma coisa quando o daemon "2ª classe" acorda e precisa ser colocado na RAM.

Agora, por que um usuário não pode usar uma linha de comando mágica para colocar um programa em swap?

  • Não está claro o que deve ser colocado na troca de uma perspectiva do espaço de usuário (não-kernel). Seu programa está vinculado a libmylib.so , deve colocar isso em swap também? E quanto a libc.so ?
  • Qual é o comportamento pretendido, na verdade? Você quer que o daemon seja colocado diretamente em swap? Mas terá que fazer algum trabalho de inicialização, não vai? Em seguida, ele retornará à RAM assim que for carregado.
  • Como você continua sabendo que o daemon não é mais usado e pode ser colocado com segurança no swap novamente?
  • Deveria ser enviado de volta ao swap diretamente ou você deveria esperar um pouco? Caso contrário, a cada sono, seu daemon será colocado em swap e a cada despertar, ele será colocado de volta na RAM. Se o seu daemon atualizar o relógio do seu computador, por exemplo, esteja pronto para horas de troca.
  • ...

Em suma, você precisa do kernel para lidar com isso e é precisamente isso que faz. Para a maioria das necessidades, ajustar a capacidade de troca é mais do que suficiente para obter um sistema responsivo.

Agora, se você realmente quiser atire no pé http://freakoutnation.com/wp-content/uploads/2013 /11/Foot-shot.jpg , o kernel oferece essa "flexibilidade" usando cgroups . Você pode obter o que você acha que deseja definindo max mem e max mem + swap para seu daemon em cgroups . Você pode obter um resultado mais razoável definindo a permeabilidade por programa. Mas de qualquer forma, não é uma boa ideia e não vou além de isso uma explicação.

    
por 15.04.2014 / 17:28
2

Há algo do tipo que você descreve: há um recurso para limitar a quantidade de RAM usada por um processo (RAM, ao contrário da memória virtual). O limite RLIMIT_RSS define um limite superior do tamanho de conjunto residente de um programa, isto é, a parte da memória desse processo que está residente na memória (em oposição a troca). No entanto, não é implementado no Linux.

RLIMIT_RSS existia em alguns sistemas Unix antigos (somente BSD?), mas foi removido de muitos sistemas modernos. Em Linux , existia apenas na série 2.4 (e mesmo assim não existia trabalhos). No Solaris foi caiu em algum momento no passado distante (quando Solaris O SunOS mudou do BSD para o System V, talvez?). O FreeBSD parece ainda tê-lo.

Não sei porque RLIMIT_RSS foi removido. Alan Cox tinha isto a dizer em 2006:

The original mm for Linux didn't enforce it as it did not have any way to track RSS that was not computationally expensive. The current mm is probably capable of implementing RSS limits although questions then still remain about what effect this has if a user sets a low RSS limit and then causes a lot of swap thrashing.

If you can see a way to implement it efficiently then go for it.

Desde então, o tópico surgiu várias vezes, mas, até onde eu sei, nenhum patch foi aceito no kernel do Linux.

Um motivo pelo qual impor um limite ao uso de memória física para um processo é que é difícil definir a quantidade de memória física que um processo está usando. Ok, conte sua pilha e heap (a parte que não foi trocada). E quanto aos arquivos mapeados na memória? Para medir o uso de memória física de um processo, você precisa contar o cache usado pelos arquivos mapeados. E quanto a bibliotecas compartilhadas e outros mapeamentos compartilhados? Se eles são usados por um único processo, então obviamente eles devem ser contados contra isso - mas quando eles são usados por múltiplos processos, é difícil saber qual processo está usando qual parte.

Não faz muito sentido limitar o uso de memória física de um único processo. Dado que os limites de recursos são herdados, cada filho poderia usar o máximo de memória física. Faz um pouco mais de sentido permitir um limite na memória física para um conjunto de processos. O Linux tem esse recurso embutido no cgroups , um sistema de virtualização parcial em que um processo e seus descendentes são executados em um contêiner que pode ter seu raiz do próprio sistema de arquivos, seus próprios controladores de rede, seus próprios limites de recursos, etc. Um uso de memória do cgroup pode ser limitado com o parâmetro memory.limit_in_bytes ( memory.memsw.limit_in_bytes controla o uso de RAM mais swap). A documentação avisa que as páginas compartilhadas entre grupos são atribuídas de maneira um pouco arbitrária (“Páginas compartilhadas são contabilizadas com base na primeira abordagem por toque). cgroup que primeiro toca uma página é contabilizada para a página. ”). Existem outras formas em que o o limite não é estritamente aplicado.

A outra parte do que você está pedindo é ter um arquivo de troca dedicado para um processo. Isso exigiria considerável complexidade no kernel. Lembre-se de que as páginas podem ser compartilhadas; qual arquivo de swap você usa se os dois processos tiverem diferentes espaços de troca atribuídos a eles? Por outro lado, o recurso pode ser implementado com bastante facilidade a partir do lado do processo: mapear um arquivo para a memória. Para páginas compartilhadas, ainda há um único arquivo. Como benefício secundário, diferentes áreas de um processo podem usar diferentes “espaços de troca”.

    
por 15.04.2014 / 18:52