Eu tenho um serviço systemd (um executor de CI) que tende a atolar o sistema com trabalhos muito intensivos da CPU. Eu peguei a média de carga voando acima de 100 agora e quero acabar com essa bobagem.
Nada mais no sistema é limitado de forma alguma, então o negócio é que eu quero que todo o resto continue como seria executado agora, mas também:
- (a) todos os processos executados como o usuário único que os jobs de CI executam ou
- (b) qualquer processo filho instanciado pelo daemon de serviço systemd
... para ficar em segundo plano em relação a todo o resto do sistema. Na verdade, eu gostaria que eles tivessem algo como um limite absoluto de 90%, mesmo quando nada mais no sistema precisa dos 10% restantes dos ciclos de CPU, mas se qualquer outra coisa solicitar tempo de CPU, eu gostaria que eles obtivessem tanto quanto eles querem primeiro.
Qual é a melhor maneira de configurar isso? Estou executando o Arch Linux no EC2 e tenho cgroups disponíveis (incluindo cgmanager), mas nunca os usei.
Em primeiro lugar, a maior parte do que aparece na pesquisa na web foi preterida. Por exemplo
cgmanager
, não há mais suporte em novas versões do systemd. Não siga 99% do que aparece em buscas na web quanto ao usocuplimit
de ,nice
,cgset
ou outras ferramentas para este trabalho. Eles não funcionarão como anunciado (como no caso de ferramentas de gerenciamento de cgroup que esperam que você crie sua própria hierarquia) ou não farão o trabalho sem recorrer a muitos hacks (como no caso de usar ' nice' para gerenciar grupos inteiros de processos).A boa notícia é que, juntamente com essas deprecações (e perseguindo o modus operandi tradicional de monstro polvo devorador de tudo do systemd), uma configuração padrão está em vigor para tudo no sistema, e ajustá-la para serviços systemd é trivial. Basta adicionar uma configuração de sobreposição ao serviço que você deseja limitar:
Adicione uma seção com os valores de controle de recursos que você deseja substituir. No meu caso cheguei a isso:
Esses valores não são todos necessários, mas os dois primeiros respondem à pergunta feita:
CPUWeight
o padrão é 100 para todos os processos no sistema. Definir um valor baixo ainda permite que o processo use a CPU se nada mais estiver efetivamente mantendo o sistema responsivo para outras tarefas, sem diminuir muito os resultados. Este é um número inteiro de peso arbitrário.CPUQuota
é um limite absoluto de quanto tempo de CPU é concedido, mesmo que nada mais esteja acontecendo. Este é um valor percentual. No meu caso, não era realmente necessário definir isso para corrigir o problema de monopolização de recursos. Acabei configurando-o de qualquer maneira para manter a temperatura da CPU baixa quando muitos trabalhos de CI se acumulam.IOWeight
é praticamente o mesmo queCPUWeight
, neste caso, usado para manter os discos livres para tarefas do sistema e apenas mantê-los ocupados com trabalhos de CI quando nada mais estiver acontecendo.MemorySwapMax
também não está no escopo da pergunta, no meu caso acabei adicionando-o porque o ray trar (povray
) em execução em alguns dos trabalhos de CI parece pensar em usar 30+ Gigs de swap além dos 30+ Gigs de RAM em este sistema é uma boa ideia só porque está lá. Ele corre mais rápido se você não o deixar usá-lo. Isso provavelmente é algo melhor configurado no povray, mas dessa forma não preciso policiar o que acontece dentro dos trabalhos de CI e não preciso desabilitar a troca do sistema.Por fim, esses valores podem ser alterados rapidamente sem reiniciar os serviços executando
systemctl daemon-reload
. Isso é bastante útil para observar o efeito das alterações imediatamente.