ulimit: Entendendo Limites de Recursos
O Que e o ulimit?
Conclusao:
ulimitmostra e altera os limites superiores de recursos (arquivos abertos, processos, memoria e mais) que um shell e os processos que ele inicia podem usar.
ulimit e 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 e herdado por processos filhos criados com fork.
As tres razoes comuns para usa-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 concorrencia
- Diminuir limites para evitar que um script descontrolado esgote recursos
Premissas
- bash e assumido (
ulimite um builtin do shell; outros shells como zsh o suportam com flags ligeiramente diferentes) - A secao de persistencia assume uma distro baseada em systemd (familia Ubuntu / RHEL)
Limites Soft vs Hard
Conclusao: O limite soft e o que e realmente aplicado; o limite hard e o teto para o limite soft. Um usuario sem privilegios pode aumentar o limite soft ate o limite hard, mas apenas root pode aumentar o limite hard.
Cada recurso tem dois valores.
| Tipo | Significado | O que um usuario sem privilegios pode fazer |
|---|---|---|
| soft | O limite atualmente aplicado | Aumentar ou diminuir, ate o limite hard |
| hard | O teto que o soft nao pode exceder | Apenas diminuir (nao pode aumenta-lo) |
Uma vez que voce diminui um limite hard, nao pode aumenta-lo novamente dentro daquela arvore 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 exibicao mostra o valor soft, mas a definicao altera ambos de uma vez -- tenha isso em mente.
Como Verificar os Limites Atuais?
Conclusao:
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
Conclusao: No dia a dia, os quatro que voce mais usa sao
-n(arquivos abertos),-u(processos),-c(core), e-s(stack).
| Flag | Recurso | Uso tipico / sintoma |
|---|---|---|
-n |
arquivos abertos | "Too many open files." O limite de file descriptor |
-u |
processos max do usuario | "fork: retry: Resource temporarily unavailable" |
-c |
tamanho do core file | Se um crash gera core dump (0 desabilita) |
-f |
tamanho de arquivo | Tamanho maximo de um unico arquivo |
-s |
tamanho da stack | Investigando segfaults de recursao profunda |
-v |
memoria virtual | Limite da memoria virtual total do processo |
-l |
max memoria bloqueada | Quanta memoria pode ser mlockada (relevante para BDs) |
-u (processos max do usuario) limita a contagem de processos para o usuario inteiro, nao apenas este shell. Parece ser por shell, mas e contado em todos os processos pertencentes ao mesmo UID.
Como Alterar um Limite Temporariamente?
Conclusao: Executar algo como
ulimit -Sn 4096afeta apenas o shell atual e os processos que ele inicia depois; fechar o shell reverte a alteracao.
# 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 e rejeitado.
$ ulimit -Sn 999999 bash: ulimit: open files: cannot modify limit: Operation not permitted
Isso requer aumentar o limite hard, o que um usuario sem privilegios nao pode fazer. Como root, voce 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 alteracao do ulimit alcanca apenas o shell que a executou e seus descendentes. Nao altera os limites de um daemon ja em execucao. Para aplicar limites a um processo ativo, use prlimit.
Como Tornar um Limite Persistente?
Conclusao: Para sessoes de login use
/etc/security/limits.d/*.conf; para servicos gerenciados pelo systemd useLimitNOFILE=na unit. Eles sao aplicados por caminhos diferentes.
Shells de login (via pam_limits)
/etc/security/limits.conf e /etc/security/limits.d/*.conf sao aplicados no login pelo modulo 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 e <dominio> <tipo> <item> <valor>, onde dominio e um nome de usuario, @nomegrupo, ou * para todos. As alteracoes so entram em vigor apos voce fazer logout e login novamente.
pam_limits nao afeta processos que nao passam por uma sessao PAM. limits.conf nao se aplica a daemons iniciados pelo systemd, o que e uma razao comum para um limite "aumentado" parecer nao ter efeito.
Servicos systemd
Para servicos gerenciados pelo systemd, defina o limite na secao [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 padrao de todos os servicos, 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 Execucao?
Conclusao: Leia
/proc/<PID>/limitsou useprlimit --pid <PID>.prlimittambem pode alterar os limites de um processo em execucao sem reinicia-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 unica 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"
Conclusao: Conte os file descriptors reais com
lsofe compare com o limite. Decida se e 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 esta fixada no limite, determine a causa.
- Vazamento de FD (descritores abertos mas nunca fechados) - corrigir a aplicacao e a solucao real; aumentar o limite apenas ganha tempo
- Legitimamente alto (alta concorrencia) - aumente o limite usando os passos de persistencia
Evite aumentar limites cegamente para unlimited. Isso mascara vazamentos de FD e pode se transformar em uma falha diferente -- esgotamento de memoria ou atingir o file-max do kernel.
Resumo
ulimitgerencia limites de recursos por processo; tenha em mente o modelo de dois niveis 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 servicos systemd -- nao confunda os caminhos - Para "Too many open files," suspeite de um vazamento de FD antes de aumentar o limite