As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Limitando o uso de recursos do processo em AL2 023 usando systemd
No Amazon Linux 2023 (AL2023), recomendamos usar systemd para controlar quais recursos podem ser usados por processos ou grupos de processos. systemdO uso é um substituto poderoso e fácil de usar para manipular cgroups manualmente ou usar utilitários comocpulimit, que antes só estavam disponíveis para o Amazon Linux em repositórios de terceirosEPEL.
Para obter informações abrangentes, consulte a systemd documentação inicial do systemd.resource-controlsystemd.resource-control em uma instância AL2 023.
Os exemplos abaixo usarão o teste de estresse da stress-ng CPU (do stress-ng pacote) para simular um aplicativo com muita CPU e memcached simular um aplicativo com muita memória.
Os exemplos abaixo abrangem a colocação de um limite de CPU em um comando único e um limite de memória em um serviço. A maioria das restrições de recursos systemd oferecidas pode ser usada em qualquer lugar systemd que execute um processo, e várias podem ser usadas ao mesmo tempo. Os exemplos abaixo são limitados a uma única restrição para fins ilustrativos.
Controle de recursos com systemd-run para executar comandos únicos
Embora comumente associado aos serviços do sistema, também systemd pode ser usado por usuários não root para executar serviços, agendar cronômetros ou executar processos pontuais. No exemplo a seguir, vamos usar stress-ng como nosso aplicativo de exemplo. No primeiro exemplo, vamos executá-lo usando systemd-run a conta ec2-user padrão e, no segundo exemplo, colocaremos limites no uso da CPU.
exemplo Use systemd-run na linha de comando para executar um processo, sem limitar o uso de recursos
-
Certifique-se de que o
stress-ngpacote esteja instalado, pois vamos usá-lo em nosso exemplo.[ec2-user ~]$sudo dnf install -ystress-ng -
Use
systemd-runpara executar um teste de estresse da CPU de 10 segundos sem limitar a quantidade de CPU que ele pode usar.[ec2-user ~]$systemd-run --user --tty --wait --property=CPUAccounting=1stress-ng --cpu 1 --timeout 10Running as unit: run-u6.service Press ^] three times within 1s to disconnect TTY. stress-ng: info: [339368] setting to a 10 second run per stressor stress-ng: info: [339368] dispatching hogs: 1 cpu stress-ng: info: [339368] successful run completed in 10.00s Finished with result: success Main processes terminated with: code=exited/status=0 Service runtime: 10.068s CPU time consumed: 9.060sA
--useropção dizsystemd-runpara executar o comando como o usuário com o qual estamos logados, a--ttyopção significa um TTY está conectado,--waitsignifica esperar até que o serviço seja concluído e a--property=CPUAccounting=1opção instruisystemd-runa registrar quanto tempo de CPU é usado na execução do processo. A opção de linha de--propertycomando pode ser usada para passarsystemd-runconfigurações que poderiam ser configuradas em um arquivosystemd.unitde configuração.
Quando instruído a colocar carga na CPU, o stress-ng programa usará todo o tempo de CPU disponível para realizar o teste durante o período solicitado. Para um aplicativo do mundo real, pode ser desejável limitar o tempo total de execução de um processo. No exemplo abaixo, solicitaremos que ela stress-ng seja executada por um período maior do que a restrição de duração máxima que impomos ao uso systemd-run dela.
exemplo Use systemd-run na linha de comando para executar um processo, limitando o uso da CPU a 1 segundo
-
Verifique se o
stress-ngestá instalado para executar este exemplo. -
A
LimitCPUpropriedade é equivalente àulimit -tqual limitará a quantidade máxima de tempo na CPU que esse processo poderá usar. Nesse caso, como estamos solicitando uma execução de estresse de 10 segundos e limitando o uso da CPU a 1 segundo, o comando receberá umSIGXCPUsinal e falhará.[ec2-user ~]$systemd-run --user --tty --wait --property=CPUAccounting=1 --property=LimitCPU=1stress-ng --cpu 1 --timeout 10Running as unit: run-u12.service Press ^] three times within 1s to disconnect TTY. stress-ng: info: [340349] setting to a 10 second run per stressor stress-ng: info: [340349] dispatching hogs: 1 cpu stress-ng: fail: [340349] cpu instance 0 corrupted bogo-ops counter, 1370 vs 0 stress-ng: fail: [340349] cpu instance 0 hash error in bogo-ops counter and run flag, 3250129726 vs 0 stress-ng: fail: [340349] metrics-check: stressor metrics corrupted, data is compromised stress-ng: info: [340349] unsuccessful run completed in 1.14s Finished with result: exit-code Main processes terminated with: code=exited/status=2 Service runtime: 1.201s CPU time consumed: 1.008s
Mais comumente, talvez você queira restringir a porcentagem de tempo de CPU que pode ser consumida por um processo específico. No exemplo abaixo, restringiremos a porcentagem de tempo de CPU que pode ser consumida pelostress-ng. Para um serviço do mundo real, pode ser desejável limitar a porcentagem máxima de tempo de CPU que um processo em segundo plano pode consumir para deixar os recursos livres para o processo que atende às solicitações do usuário.
exemplo Use systemd-run para limitar um processo a 10% do tempo de CPU em uma CPU
-
Verifique se o
stress-ngestá instalado para executar este exemplo. -
Vamos usar a
CPUQuotapropriedade to tellsystemd-runpara restringir o uso da CPU para o comando que vamos executar. Não estamos limitando a quantidade de tempo que o processo pode ser executado, apenas a quantidade de CPU que ele pode usar.[ec2-user ~]$systemd-run --user --tty --wait --property=CPUAccounting=1 --property=CPUQuota=10%stress-ng --cpu 1 --timeout 10Running as unit: run-u13.service Press ^] three times within 1s to disconnect TTY. stress-ng: info: [340664] setting to a 10 second run per stressor stress-ng: info: [340664] dispatching hogs: 1 cpu stress-ng: info: [340664] successful run completed in 10.08s Finished with result: success Main processes terminated with: code=exited/status=0 Service runtime: 10.140s CPU time consumed: 1.014sObserve como o CPU a contabilidade nos diz que, embora o serviço tenha sido executado por 10 segundos, ele consumiu apenas 1 segundo do tempo real de CPU.
Há várias maneiras de configurar systemd para limitar o uso de recursos para CPU, memória, rede e E/S. Consulte a systemd documentação inicial para systemd.resource-controlsystemd.resource-control em uma instância AL2 023 para uma documentação abrangente.
Nos bastidores, systemd está usando recursos do kernel Linux, como cgroups implementar esses limites, evitando a necessidade de configurá-los manualmente. A documentação do Linux Kernel cgroup-v2cgroups trabalho.
Controle de recursos em um systemd serviço
Há vários parâmetros que podem ser adicionados à [Service] seção de systemd serviços para controlar o uso dos recursos do sistema. Isso inclui limites rígidos e flexíveis. Para saber o comportamento exato de cada opção, consulte a systemd documentação inicial do systemd.resource-controlsystemd.resource-control em uma instância AL2 023.
Os limites comumente usados são MemoryHigh especificar um limite de limitação no uso da memória, MemoryMax definir um limite máximo rígido (que, uma vez atingido, o OOM Killer é invocado) e CPUQuota (conforme ilustrado na seção anterior). Também é possível configurar pesos e prioridades em vez de números fixos.
exemplo Usando systemd para definir limites de uso de memória nos serviços
Neste exemplomemcached, definiremos um limite de uso de memória rígida para um cache simples de valores-chave e mostraremos como o OOM Killer é invocado para esse serviço e não para todo o sistema.
-
Primeiro, precisamos instalar os pacotes necessários para este exemplo.
[ec2-user ~]$sudo dnf install -ymemcached libmemcached-awesome-tools -
Ative o
memcached.servicee, em seguida, inicie o serviço para que elememcachedesteja em execução.[ec2-user ~]$sudo systemctl enablememcached.serviceCreated symlink /etc/systemd/system/multi-user.target.wants/memcached.service → /usr/lib/systemd/system/memcached.service.[ec2-user ~]$sudo systemctl startmemcached.service -
Verifique se
memcached.serviceestá em execução.[ec2-user ~]$sudo systemctl statusmemcached.service● memcached.service - memcached daemon Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled) Active: active (running) since Fri 2025-01-31 22:36:42 UTC; 1s ago Main PID: 356294 (memcached) Tasks: 10 (limit: 18907) Memory: 1.8M CPU: 20ms CGroup: /system.slice/memcached.service └─356294 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1 Jan 31 22:35:36 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon. -
Agora que
memcachedestá instalado e em execução, podemos observar que ele funciona inserindo alguns dados aleatórios no cache/etc/sysconfig/memcachedNaCACHESIZEvariável é definida como 64 por padrão, o que significa 64 megabytes. Ao inserir mais dados no cache do que o tamanho máximo do cache, podemos ver que preenchemos o cache e alguns itens são removidos usandomemcached-tool, e que estão usando cerca de 64 MB de memória.memcached.service[ec2-user ~]$for i in $(seq 1 150); do dd if=/dev/random of=$i bs=512k count=1; memcp -s localhost $i; done[ec2-user ~]$memcached-tool localhost display# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM 2 120B 0s 1 0 no 0 0 0 39 512.0K 4s 63 126 yes 24 2 0[ec2-user ~]$sudo systemctl statusmemcached.service● memcached.service - memcached daemon Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled) Active: active (running) since Fri 2025-01-31 22:36:42 UTC; 7min ago Main PID: 356294 (memcached) Tasks: 10 (limit: 18907) Memory: 66.7M CPU: 203ms CGroup: /system.slice/memcached.service └─356294 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1 Jan 31 22:36:42 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon. -
Use a
MemoryMaxpropriedade para definir um limite rígido paramemcached.serviceonde, se atingido, o OOM Killer será invocado. Opções adicionais podem ser definidas para o serviço adicionando-as a um arquivo de substituição. Isso pode ser feito editando diretamente o/etc/systemd/system/memcached.service.d/override.confarquivo ou interativamente usando oeditcomando desystemctl.[ec2-user ~]$sudo systemctl editmemcached.serviceAdicione o seguinte à substituição para definir um limite rígido de 32 MB de memória para o serviço.
[Service] MemoryMax=32M -
Diga
systemdpara recarregar sua configuração[ec2-user ~]$sudo systemctl daemon-reload -
Observe que agora
memcached.serviceestá sendo executado com um limite de memória de 32 MB.[ec2-user ~]$sudo systemctl statusmemcached.service● memcached.service - memcached daemon Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled) Drop-In: /etc/systemd/system/memcached.service.d └─override.conf Active: active (running) since Fri 2025-01-31 23:09:13 UTC; 49s ago Main PID: 358423 (memcached) Tasks: 10 (limit: 18907) Memory: 1.8M (max: 32.0M available: 30.1M) CPU: 25ms CGroup: /system.slice/memcached.service └─358423 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1 Jan 31 23:09:13 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon. -
O serviço funcionará normalmente usando menos de 32 MB de memória, o que podemos verificar carregando menos de 32 MB de dados aleatórios no cache e, em seguida, verificando o status do serviço.
[ec2-user ~]$for i in $(seq 1 30); do dd if=/dev/random of=$i bs=512k count=1; memcp -s localhost $i; done[ec2-user ~]$sudo systemctl statusmemcached.service● memcached.service - memcached daemon Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled) Drop-In: /etc/systemd/system/memcached.service.d └─override.conf Active: active (running) since Fri 2025-01-31 23:14:48 UTC; 3s ago Main PID: 359492 (memcached) Tasks: 10 (limit: 18907) Memory: 18.2M (max: 32.0M available: 13.7M) CPU: 42ms CGroup: /system.slice/memcached.service └─359492 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1 Jan 31 23:14:48 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon. -
Agora podemos
memcachedusar mais de 32 MB de memória tentando usar todos os 64 MB de cache que são a configuração padrãomemcached.[ec2-user ~]$for i in $(seq 1 150); do dd if=/dev/random of=$i bs=512k count=1; memcp -s localhost $i; doneVocê observará que em algum momento durante o comando acima, há erros de conexão com o
memcachedservidor. Isso ocorre porque o OOM Killer encerrou o processo devido à restrição que impusemos a ele. O restante do sistema funcionará normalmente e nenhum outro processo será considerado pelo OOM Killer, pois é apenas omemcached.serviceque restringimos.[ec2-user ~]$sudo systemctl statusmemcached.service● memcached.service - memcached daemon Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled) Drop-In: /etc/systemd/system/memcached.service.d └─override.conf Active: failed (Result: oom-kill) since Fri 2025-01-31 23:20:28 UTC; 2s ago Duration: 2.901s Process: 360130 ExecStart=/usr/bin/memcached -p ${PORT} -u ${USER} -m ${CACHESIZE} -c ${MAXCONN} $OPTIONS (code=killed, signal=KILL) Main PID: 360130 (code=killed, signal=KILL) CPU: 94ms Jan 31 23:20:25 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon. Jan 31 23:20:28 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: memcached.service: A process of this unit has been killed by the OOM killer. Jan 31 23:20:28 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: memcached.service: Main process exited, code=killed, status=9/KILL Jan 31 23:20:28 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: memcached.service: Failed with result 'oom-kill'.