ulimit: Entendendo Limites de Recursos
O Que é o ulimit?
Conclusão:
ulimitmostra e altera os limites superiores de recursos (arquivos abertos, processos, memória e mais) que um shell e os processos que ele inicia podem usar.
ulimit é um builtin do shell (no bash e shells similares) que chama getrlimit(2) / setrlimit(2) do kernel para ler e definir limites de recursos. Um limite se aplica por processo e é herdado por processos filhos criados com fork.
As três razões comuns para usá-lo:
- Diagnosticar erros de esgotamento de limites como "Too many open files"
- Aumentar limites para que bancos de dados e servidores web possam lidar com sua concorrência
- Diminuir limites para evitar que um script descontrolado esgote recursos
Premissas
- bash é assumido (
ulimité um builtin do shell; outros shells como zsh o suportam com flags ligeiramente diferentes) - A seção de persistência assume uma distro baseada em systemd (família Ubuntu / RHEL)
Limites Soft vs Hard
Conclusão: O limite soft é o que é realmente aplicado; o limite hard é o teto para o limite soft. Um usuário sem privilégios pode aumentar o limite soft até o limite hard, mas apenas root pode aumentar o limite hard.
Cada recurso tem dois valores.
| Tipo | Significado | O que um usuário sem privilégios pode fazer |
|---|---|---|
| soft | O limite atualmente aplicado | Aumentar ou diminuir, até o limite hard |
| hard | O teto que o soft não pode exceder | Apenas diminuir (não pode aumentá-lo) |
Uma vez que você diminui um limite hard, não pode aumentá-lo novamente dentro daquela árvore de processos (aumentar requer root, ou seja, CAP_SYS_RESOURCE). No ulimit, flags selecionam o alvo.
$ ulimit -Sn # mostra o limite soft de arquivos abertos $ ulimit -Hn # mostra o limite hard de arquivos abertos
-S: atua no limite soft-H: atua no limite hard- Se omitido: a exibição mostra o valor soft, mas a definição altera ambos de uma vez -- tenha isso em mente.
Como Verificar os Limites Atuais?
Conclusão:
ulimit -alista o limite soft atual para cada recurso; use uma flag individual como-npara inspecionar um recurso.
$ ulimit -a
real-time non-blocking time (microseconds, -R) unlimited core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 15363 max locked memory (kbytes, -l) 8192 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 8192 max user processes (-u) 15363 virtual memory (kbytes, -v) unlimited
-a imprime valores soft. Para ver todos os limites hard de uma vez, use ulimit -aH.
$ ulimit -aH # limites hard para cada recurso
Os Principais Tipos de Recursos
Conclusão: No dia a dia, os quatro que você mais usa são
-n(arquivos abertos),-u(processos),-c(core), e-s(stack).
| Flag | Recurso | Uso típico / sintoma |
|---|---|---|
-n |
arquivos abertos | "Too many open files." O limite de file descriptor |
-u |
processos max do usuário | "fork: retry: Resource temporarily unavailable" |
-c |
tamanho do core file | Se um crash gera core dump (0 desabilita) |
-f |
tamanho de arquivo | Tamanho máximo de um único arquivo |
-s |
tamanho da stack | Investigando segfaults de recursão profunda |
-v |
memória virtual | Limite da memória virtual total do processo |
-l |
max memória bloqueada | Quanta memória pode ser mlockada (relevante para BDs) |
-u (processos max do usuário) limita a contagem de processos para o usuário inteiro, não apenas este shell. Parece ser por shell, mas é contado em todos os processos pertencentes ao mesmo UID.
Como Alterar um Limite Temporariamente?
Conclusão: Executar algo como
ulimit -Sn 4096afeta apenas o shell atual e os processos que ele inicia depois; fechar o shell reverte a alteração.
# Aumentar o limite soft de arquivos abertos para 4096 (dentro do limite hard) $ ulimit -Sn 4096 # Verificar $ ulimit -Sn 4096
Solicitar mais do que o limite hard é rejeitado.
$ ulimit -Sn 999999 bash: ulimit: open files: cannot modify limit: Operation not permitted
Isso requer aumentar o limite hard, o que um usuário sem privilégios não pode fazer. Como root, você pode alterar ambos de uma vez:
# somente root. Define soft e hard juntos para 65536 $ sudo bash -c 'ulimit -n 65536; exec your-server'
Uma alteração do ulimit alcanca apenas o shell que a executou e seus descendentes. Não altera os limites de um daemon já em execução. Para aplicar limites a um processo ativo, use prlimit.
Como Tornar um Limite Persistente?
Conclusão: Para sessões de login use
/etc/security/limits.d/*.conf; para serviços gerenciados pelo systemd useLimitNOFILE=na unit. Eles são aplicados por caminhos diferentes.
Shells de login (via pam_limits)
/etc/security/limits.conf e /etc/security/limits.d/*.conf são aplicados no login pelo módulo PAM pam_limits. Isso cobre shells iniciados por login SSH ou login.
# /etc/security/limits.d/90-nofile.conf * soft nofile 8192 * hard nofile 65536 deploy soft nproc 4096
O formato é <dominio> <tipo> <item> <valor>, onde dominio é um nome de usuário, @nomegrupo, ou * para todos. As alterações só entram em vigor após você fazer logout e login novamente.
pam_limits não afeta processos que não passam por uma sessão PAM. limits.conf não se aplica a daemons iniciados pelo systemd, o que é uma razão comum para um limite "aumentado" parecer não ter efeito.
Serviços systemd
Para serviços gerenciados pelo systemd, defina o limite na seção [Service] da unit.
# /etc/systemd/system/myapp.service.d/override.conf [Service] LimitNOFILE=65536 LimitNPROC=4096
$ sudo systemctl daemon-reload $ sudo systemctl restart myapp
Para alterar o padrão de todos os serviços, edite DefaultLimitNOFILE= em /etc/systemd/system.conf. Verifique o valor efetivo com systemctl show myapp -p LimitNOFILE.
Como Inspecionar os Limites de um Processo em Execução?
Conclusão: Leia
/proc/<PID>/limitsou useprlimit --pid <PID>.prlimittambém pode alterar os limites de um processo em execução sem reiniciá-lo.
$ cat /proc/1234/limits
Limit Soft Limit Hard Limit Units Max open files 1024 524288 files Max processes 15363 15363 processes ...
prlimit verifica e altera limites em uma única linha.
# Inspecionar $ prlimit --pid 1234 --nofile # Alterar soft/hard de um processo em execucao para 8192 (pode precisar de privilegios) $ sudo prlimit --pid 1234 --nofile=8192:8192 # Iniciar um comando com um limite aplicado $ prlimit --nofile=4096:4096 ./myserver
Corrigindo "Too many open files"
Conclusão: Conte os file descriptors reais com
lsofe compare com o limite. Decida se é um vazamento de FD ou um limite genuinamente insuficiente antes de agir.
"Too many open files" significa que o limite de arquivos abertos (-n) foi atingido. Resolva da seguinte forma.
- Identifique o PID do processo afetado
- Verifique seu limite efetivo (
cat /proc/<PID>/limits) - Conte quantos descritores ele tem abertos atualmente
# Contar os FDs que um processo tem abertos $ lsof -p 1234 | wc -l
- Se a contagem está fixada no limite, determine a causa.
- Vazamento de FD (descritores abertos mas nunca fechados) - corrigir a aplicação e a solução real; aumentar o limite apenas ganha tempo
- Legitimamente alto (alta concorrência) - aumente o limite usando os passos de persistência
Evite aumentar limites cegamente para unlimited. Isso mascara vazamentos de FD e pode se transformar em uma falha diferente -- esgotamento de memória ou atingir o file-max do kernel.
Resumo
ulimitgerencia limites de recursos por processo; tenha em mente o modelo de dois níveis soft/hard- Altere temporariamente com
ulimit -Sn N; inspecione comulimit -a,/proc/<PID>/limits, ouprlimit - Persista via
limits.d/*.confpara logins, ouLimitNOFILE=da unit para serviços systemd -- não confunda os caminhos - Para "Too many open files," suspeite de um vazamento de FD antes de aumentar o limite