Como alocar memória dinamicamente para o ambiente do AWS Elastic Beanstalk de contêiner com várias janelas de encaixe executando aplicativos Java

8

Eu quero espremer cada grama de uso possível da camada de elástico livre do pé de feijão.

Meu back-end é construído como um conjunto de microsserviços (usando o ktor). Eu tenho 5 microsserviços para ser mais preciso. Tudo isso é dockerizado e eu estou tentando executá-los na mesma pequena instância do t2.micro (free) elástico beanstalk com o ambiente de imagem multi-docker

Java sendo java, ele gosta de ocultar cerca de 200 MB de RAM por contêiner de docker, mesmo para o microsserviço mais simples.

Então, o t2.micro fornece 1 GB de RAM. Eu tenho 5 contêineres de docker para microsserviços que exigem pelo menos 200 MB cada = muito perto.

O problema é que a memória quase sempre está pairando ferozmente perto de 100% quase o tempo todo.

Portanto, existe uma maneira de alocar dinamicamente a memória para os contêineres do docker, dependendo de quanto está livre e com que desespero um contêiner precisa?

Digamos que um contêiner esteja fazendo algum trabalho pesado enquanto os outros estão ociosos. Quero direcionar alguma RAM para o contêiner que está executando a tarefa pesada e, depois que a tarefa terminar, volte à alocação de RAM igual por contêiner.

Existe uma maneira de fazer isso?

Aditya Anand
fonte

Respostas:

1

Você pode usar docker update --memory-reservation xxx <container>para alterar a alocação de memória de limite suave para um contêiner enquanto estiver em execução. O Docker empurrará suavemente os contêineres para seus limites flexíveis quando a memória geral estiver baixa. Assim, você pode definir limites suaves de, digamos, 150 MB para todos os seus contêineres e depois aumentar um deles quando souber que ele tem trabalho extra a fazer.

A documentação do docker sobre limites flexíveis não é tão boa assim, a documentação do kernel do CGroup Memory explica melhor.

CantankerousBullMoose
fonte
Obrigado, vou analisar mais isso. Embora, idealmente, eu queira uma solução que, por exemplo: monitore dinamicamente o uso de memória de vários contêineres e ofereça mais memória àquele que está executando muito próximo do mais alto a qualquer momento (para maximizar o desempenho). Portanto, em um servidor, não seria realmente possível alterar manualmente os limites, pois eles podem depender do cronograma do trabalho, do tráfego etc.
Aditya Anand
Como isso é diferente de não ter gerenciamento de memória? Se uma instância da JVM em um contêiner estiver solicitando alocação de memória e outra instância da JVM em outro contêiner estiver mantendo o espaço de heap não utilizado, a segunda JVM desistirá e permitirá que a primeira a tenha ... Certo?
CantankerousBullMoose 30/01
É assim mesmo? Você pode criar um link para uma fonte autorizada sobre o assunto? Na minha experiência, parece ser um pouco aleatório. Às vezes, uma instância opta por manter um heap não utilizado, mesmo que passe fome pela outra instância; nesse caso, as outras instâncias começam a usar uma quantidade maior de memória paginada, o que torna as coisas mais lentas.
Aditya Anand
1
Isso está começando a parecer mais um problema Java do que um docker. Não passei muito tempo brincando com eles, mas o -XX: MaxHeapFreeRatio e -XX: MinHeapFreeRatio devem controlar o quão agressivamente a JVM leva e fornece memória do sistema operacional. Talvez isso lhe desse resultados mais consistentes? Os documentos do Oracle sobre Garbage Collection têm alguns detalhes sobre esses sinalizadores.
CantankerousBullMoose 31/01
Sim, novamente, isso realmente apenas controla a configuração estática inicial que eu posso fornecer um processo java, não como gerenciar dinamicamente a memória alocada para diferentes processos com base na necessidade.
Aditya Anand