Descritores de Arquivos e Swappiness

O que são Descritores de Arquivos (File-Descriptors) e Swappiness. Veremos na prática como funcionam e em quais casos é necessário alterar os valores.

[ Hits: 213 ]

Por: Buckminster em 30/04/2025


Descritores de Arquivos



Para ver tudo:

sudo prlimit --pid 2040

RESOURCE DESCRIPTION SOFT HARD UNITS
AS limite de espaço de endereços ilimitado ilimitado bytes
CORE tamanho máximo de arquivo do núcleo 0 ilimitado bytes
CPU Tempo da CPU ilimitado ilimitado segundos
DATA tamanho máximo de dados ilimitado ilimitado bytes
FSIZE tamanho máximo de arquivo ilimitado ilimitado bytes
LOCKS número máximo de travas de arquivo man ilimitado ilimitado travas
MEMLOCK espaço máximo de endereço travado na m 4161884160 4161884160 bytes
MSGQUEUE máximo de bytes nos módulos POSIX 819200 819200 bytes
NICE prioridade máxima de nice permitida 0 0
NOFILE número máximo de arquivos abertos 1024 1048576 arquivos
NPROC número máximo de processos 126639 126639 processo
RSS tamanho máximo de conjunto residente ilimitado ilimitado bytes
RTPRIO prioridade máxima de tempo real 0 0
RTTIME tempo limite para tarefas em tempo rea ilimitado ilimitado microsse
SIGPENDING número máximo de sinais pendentes 126639 126639 sinais
STACK tamanho máximo da pilha 8388608 ilimitado bytes


Na saída do comando

$ lsof -p $(echo $$)

vemos os arquivos abertos pela sessão do shell. Repare na coluna FD (File Descriptors) os arquivos 0u, 1u e 2u.

São, respectivamente, os descritores de arquivo stdin, stdout e stderr.

Os descritores de arquivo não tem somente um número, também tem um nome, uma string.


Nessa imagem vemos a saída do comando
$ cat /proc/sys/fs/file-max
9223372036854775807
Isso é coisa do famigerado Systemd:

"Após discussões com o pessoal do Kernel um sistema com memcg realmente não deveria mais precisar de limites rígidos extras para descritores de arquivo já que eles são devidamente contabilizados pelo memcg de qualquer maneira. Portanto, vamos aumentar esses valores para seus valores máximos. Isso também adiciona uma opção em tempo de compilação para desativar isso para atender aos usuários que não desejam usar o memcg.

55

Os sysctls fs.nr_open e fs.file-max agora são automaticamente elevados para os valores mais altos possíveis, pois a contabilização separada de descritores de arquivo não é mais necessária porque o memcg já os rastreia corretamente como parte da contabilização de memória. Assim, dos quatro limites para descritores de arquivo atualmente aplicados (fs.file-max, fs.nr_open, RLIMIT_NOFILE hard, RLIMIT_NOFILE soft) desativamos os dois primeiros e mantemos apenas os dois últimos.

Um conjunto de opções em tempo de compilação (-Dbump-proc-sys-fs-file-max=no e -Dbump-proc-sys-fs-nr-open=no) foi adicionado para reverter essa mudança de comportamento, o que pode ser uma opção para sistemas que desativam o memcg no kernel.

1168

Vamos aumentar fs.file-max e fs.nr_open para seus respectivos máximos. Nos Kernels atuais um grande número de descritores de arquivo não representa mais um problema de desempenho e sua memória é rastreada adequadamente pelo memcg, contá-los e limitá-los em mais duas camadas de limites é desnecessário e apenas complica as coisas. Esta função, portanto, desativa 2 dos 4 níveis de limites para descritores de arquivo e torna RLIMIT_NOLIMIT (soft + hard) os únicos que realmente importam.

1199

Arg! O kernel impõe valores máximos e mínimos em fs.nr_open, mas não sabemos exatamente quais são. A expressão pela qual o máximo é determinado depende da arquitetura e é algo que não queremos copiar para o espaço do usuário, pois depende dos detalhes de implementação do kernel. Como o kernel não nos expõe o valor máximo, só nos resta tentar e torcer. Portanto, vamos começar com INT_MAX e, em seguida, reduzir o valor pela metade até encontrarmos um que funcione. Feio? Sim, com certeza, mas APIs do kernel são APIs do kernel, então o que podemos fazer..."

Confira aqui:


Veremos na prática.

  • [i]fs.file-max[/i] é o número máximo de descritores de arquivo que todo o sistema Linux pode ter aberto ao mesmo tempo.
  • [i]fs.nr_open[/i] é o número máximo de descritores de arquivo que um único processo pode abrir.

Foi esses dois que o Systemd liberou até o máximo delimitado pelo Kernel (unlimited, lembrando que 'unlimited' não significa um valor infinito).

cat /proc/sys/fs/file-max

9223372036854775807

cat /proc/sys/fs/nr_open

1048576

O máximo delimitado pelo Kernel é o valor que aparece ali nas saídas, então vemos que, de certa maneira, o Systemd está certo em liberar esse limites, pois o Kernel já os limita.

Isso inclui arquivos normais, sockets, pipes, etc.

  • soft é o limite atual que um processo pode usar normalmente;
  • hard é o limite máximo que o soft pode ser elevado (sem privilégios).
  • O Soft limit pode ser alterado pelo próprio processo — até o valor de hard.
  • O Hard limit só pode ser aumentado pelo root (ou com permissões elevadas - sudo, su, etc).

Contudo, agora entenderemos na prática.

O comando ulimit modifica limites de recursos do shell, até fechar o terminal.

ulimit --help

  • O parâmetro -S usa um limite 'soft' de recursos;
  • O parâmetro -H usa um limite 'hard' de recursos;
  • O parâmetro -u o número máximo de processos de usuário;
  • O parametro -n o número máximo de descritores de arquivo abertos;
  • O parâmetro -a todos os limites atuais são relatados

ulimit -S

unlimited

ulimit -H

unlimited

ulimit -u

29196

ulimit -n

1024

Limite Soft:

ulimit -Sn

1024

Limite Hard:

ulimit -Hn

1048576

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) 29196
max locked memory (kbytes, -l) 951984
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 29196
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited


Valores padrões no Kernel do Debian 12.

uname -r

6.1.0-33-amd64

No arquivo do Systemd citado anteriormente vemos nas linhas 1187 e 1230, respectivamente:

r = sysctl_write("fs/file-max", t); e
r = sysctl_write("fs/nr_open", t);

onde vê-se que os valores aumentados até o máximo são aqueles constantes nos arquivos /proc/sys/fs/file-max e /proc/sys/fs/nr_open.

cat /proc/sys/fs/file-max

9223372036854775807

cat /proc/sys/fs/nr_open

1048576

Então os limites Soft e Hard ("...torna RLIMIT_NOLIMIT (soft + hard) os únicos que realmente importam...") são os que realmente importam: ulimit -Sn e ulimit -Hn.

Porém, vemos que a saída de 'ulimit -Hn' é a mesma de 'cat /proc/sys/fs/nr_open': 1048576, sendo que -Hn é o limite Hard e nr_open é o número máximo de descritores de arquivo que um único processo pode abrir.

Testei em 4 máquinas com Debian 12 e as saídas padrões foram as mesmas.

O que se entende é que o limite Hard é o número máximo de descritores de arquivo que um único processo pode abrir. Um único processo pode abrir 1.048.576 descritores de arquivo.

O limite Soft é 1024, porém, o limite Soft não é exatamente um limite mínimo, o limite Soft é um valor inicial.

No caso, limite Soft só pode ser mudado até 1048576 (saída de ulimit -Hn), mais do que isso causará um erro, pois é tratado no Kernel.

Tente colocar um valor maior do que 1048576 (saída de ulimit -Hn):

ulimit -n 1048576346

bash: ulimit: open files: impossível modificar limite: Operação não permitida

Como root:

# ulimit -n 10485761

-bash: ulimit: open files: impossível modificar limite: Operação não permitida

O limite Soft pode ser alterado para menos do que o limit de 1024:

# ulimit -n 10
# ulimit -Sn
10
ulimit -n 2
ulimit -Sn
2

Porém, como já foi dito isso vale só até fechar e abrir o terminal (Shell).

Depois o valor volta a 1024.

Acredito que o Systemd está certo porque se o próprio Kernel já limita os descritores de arquivo (unlimited não significa um valor infinito), não faz sentido limitar duas vezes os valores fs.nr_open e fs.file-max.

E atualmente os computadores trabalham com memória RAM generosa em relação à antigamente.

Essa limitação dos descritores de arquivo afetam somente máquinas muito antigas oque é natural, pois ninguém espera que um computador dure para sempre em relação a seu hardware.

Apesar de que os computadores de naves espaciais tem um hardware considerado obsoleto hoje e com pouca RAM, isso tem pouco a ver com descritores de arquivo, pois eles trabalham basicamente com cálculos.

Os descritores de arquivo são armazenados na memória RAM, a swappiness no disco (HD ou SD).

MODIFICANDO OS LIMITES

Execute:

cat /proc/sys/fs/file-nr

Exemplo da saída:

11808 0 9223372036854775807

O primeiro número é o uso atual que mostra quantos descritores (ou identificadores) de arquivo estão atualmente alocados no sistema inteiro.

O segundo valor indica o número de descritores de arquivo alocados, mas não utilizados.

O terceiro número indica o número máximo de descritores de arquivo.

O Linux Kernel 2.6 e versões posteriores sempre relatam 0 como o número de descritores de arquivo livres — isso não é um erro, significa apenas que o número de descritores de arquivo alocados corresponde exatamente ao número de identificadores de arquivo utilizados.


Se o primeiro valor estiver perto do terceiro valor é hora de aumentar o número de descritores de arquivo.

1. Vendo o limite atual

ulimit -Sn # soft limit

1024

ulimit -Hn # hard limit

1048576

O limite Soft (inicial) padrão geralmente é o mesmo para as várias distribuições, o limite Hard (máximo) pode mudar.

2. Aumentar limite por processo (permanente)

sudo vim /etc/security/limits.conf

Adicione essas linhas no final ou descomente:

* soft nofile 1048576
* hard nofile 1048576

O * aplica pra todos os usuários.

Pode trocar o * por um nome de usuário específico, caso quiser, por exemplo:

usuario soft nofile 65536
usuario hard nofile 1048576

*O valor a ser colocado depende da sua carga de trabalho.

Como já dito, caso for desktop/laptop de uso diário/cotidiano não precisa alterar nada.

Caso estiver usando PAM — geralmente sim -, Verifique se esses arquivos existem e têm a linha "session required pam_limits.so" habilitada:

cat /etc/pam.d/common-session
cat /etc/pam.d/common-session-noninteractive

Adicione (ou descomente) a linha neles:

session required pam_limits.so

Como já dito, caso for desktop/laptop de uso diário/cotidiano não precisa alterar nada.

3. Editar fs.nr_open e fs.file-max (limites do kernel)

Temporário:

sudo sysctl -w fs.nr_open=65536
sudo sysctl -w fs.file-max=1048576

cat /proc/sys/fs/file-max

1048576

cat /proc/sys/fs/nr_open

1048576

AVISO IMPORTANTE
Não coloque o parâmetro fs.nr_open no sysctl.conf com um valor menor do que a saída de cat [i]/proc/sys/fs/nr_open[/i].

Caso colocar um valor menor isso travará o Systemd na primeira reinicialização tendo que acessar com um sistema Live para comentar o parâmetro.

Teste primeiro colocando um valor maior do que a saída de cat /proc/sys/fs/nr_open e execute:

sudo sysctl -p

Feche o terminal e tente abrir o terminal novamente, caso não abrir mais o terminal execute Ctrl+Alt+F1 ou F2 ou F3, etc (depende do sistema) que abrirá o login sem interface gráfica. Logue como root e comente o valor em fs.nr_open e execute sysctl -p e depois reboot:

Ctrl+Alt+F1 Logue como root.

# nano /etc/sysctl.conf

Comente o parâmetro.

Salve e saia.

# sysctl -p
# reboot

Aconselho a não mexer no parâmetro nr_open caso a saída deste já estiver num valor alto como 1048576 em relação à saída de ulimit -Sn.

Lembram que eu mencionei antes:

"Vejam bem, falei "difícil", não impossível, mas essa é uma outra discussão que não cabe agora no momento.

Veremos adiante que "malware" pode ser qualquer software que trava/prejudica o sistema, como a própria definição do limite nr_open, como veremos adiante na seção MODIFICANDO OS LIMITES > AVISO IMPORTANTE."

Permanente:

Adicione ao final do [i]/etc/sysctl.conf[/i]:

fs.file-max=1048576

E depois aplique:

sudo sysctl -p

O arquivo /etc/security/limits.conf só pode definir limites de recursos para usuários que efetuam login por meio do PAM; ele não afeta os limites de recursos dos serviços do sistema.

Portanto, quando sev inicia um serviço, por exemplo, com "sudo systemctl start servico" ou "sudo service servico start" este serviço não será afetado pelas limitações em /etc/security/limits.conf.

O número máximo de descritores de arquivo disponíveis para serviços de sistemas com Systemd é determinado pelo parâmetro DefaultLimitNOFILE no arquivo /etc/systemd/system.conf ou pelo parâmetro LimitNOFILE no arquivo /usr/lib/systemd/system/.service.

O primeiro é uma configuração padrão global aplicada a todos os serviços do sistema enquanto que o último é um limite individual opcional para cada serviço. LimitNOFILE substituirá DefaultLimitNOFILE.

4. Se estiver usando Systemd temos duas maneiras de fazer: se quiser alterar os descritores para cada processo (programa, aplicativo, etc) com um valor específico, caso não, altere somente o arquivo /etc/systemd/system.conf.

4.1- Editar o arquivo ".service":

sudo systemctl edit nome-do-servico

Acrescente na posição indicada:

[Service]
LimitNOFILE=1024:1048576

Salve e saia.

4.2- Altere o arquivo /etc/systemd/system.conf
Perceba que você pode alterar nesse arquivo os vários limites de Soft e Hard para cada serviço básico: CPU, MEMLOCK, etc.
Ou altere somente o DefaultLimitNOFILE=1024:1048576 que valerá como padrão para todos os serviços controlados pelo Systemd.
Depois para o caso 4.1:

sudo systemctl daemon-reload
sudo systemctl restart nome-do-servico

Para o caso 4.2:

sudo systemctl daemon-reexec
sudo systemctl daemon-reload

5. Para verificar se um serviço ou processo está com o novo limite:

cat /proc//limits

Ou, com lsof:

lsof -p | wc -l

Para ver o [i]PID[/i]:

pidof nome_processo

pidof apache2

1020 1019 1018 1017 1016 1015

Ou

top

ou

htop

ou

ps aux | grep nome_servico
ps aux | grep java

kluster 37360 0.0 0.0 6352 2076 pts/0 S+ 08:47 0:00 grep java

O [i]PID[/i] é o primeiro número da linha, no caso: 37360.

cat /proc/37360/limits

cat: /proc/37360/limits: Arquivo ou diretório inexistente

lsof -p 37360 | wc -l

0


PID Pulseaudio: $ cat /proc/1298/limits

INFORMAÇÕES EXTRAS

Para verificar os limites de cada processo com um PID no diretório /proc:

cat /proc//limits

Ou, com lsof:

lsof -p | wc -l

Para ver o PID:

top

ou

htop

ou

ps aux | grep nome_servico
ps aux | grep java

kluster 37360 0.0 0.0 6352 2076 pts/0 S+ 08:47 0:00 grep java

O [i]PID[/i] é o primeiro número da linha, no caso: 37360.

cat /proc/37360/limits

cat: /proc/37360/limits: Arquivo ou diretório inexistente

lsof -p 37360 | wc -l

0

Essas saídas significam que está ilimitado.

Nem todo processo cria um diretório PID dentro de /proc.

Exemplo:

ps aux | grep pulseaudio


kluster 1298 0.0 0.3 842804 29244 ? S<sl 07:49 0:00 /usr/bin/pulseaudio --daemonize=no --log-target=journal
kluster 121329 0.0 0.0 6352 2180 pts/0 S+ 11:11 0:00 grep pulseaudio


Temos dois PIDs, daremos cat em cada um:

cat /proc/121329/limits

cat: /proc/121329/limits: Arquivo ou diretório inexistente


$ cat /proc/1298/limits
Vemos que o PID do pulseaudio tem um diretório <PID> dentro de /proc, enquanto que o outro PID (que não é do pulseaudio, mas do grep) não criou um diretório em /proc, o que é óbvio, pois é um comando do shell e é temporário.
Podemos ver que cada coisa que se faz no Linux cria um PID e, no mínimo, um descritor de arquivo que são "apagados" depois de acordo com as suas atribuições.
Veja:

ps aux | grep pulseaudio


kluster 1298 0.0 0.3 842804 29244 ? S<sl 07:49 0:00 /usr/bin/pulseaudio --daemonize=no --log-target=journal
kluster 131308 0.0 0.0 6352 2168 pts/0 S+ 11:27 0:00 grep pulseaudio


Já foi criado um novo [i]PID[/i] para o 'grep pulseaudio' enquanto que o [i]PID[/i] do Pulseaudio permanece o mesmo.

Agora vamos entrar no diretório /proc:

cd /proc
ls


1 1358 16 26 46383 62693 8215 cgroups locks
10 1364 160 262 46396 631 8219 cmdline meminfo
10261 1367 161 2690 47 642 8227 consoles misc
10271 1372 162 29 48 649 8235 cpuinfo modules
102741 1386 163 291 4828 65 8487 crypto mounts


Coloquei somente as 5 primeiras linhas.

Entrando num diretório PID:

cd 1372
ls


Entrando em um diretório /proc/pid.

Vendo o conteúdo do arquivo limits.
Vemos que a trama se complica, pois tem vários limites Soft e vários limites Hard.
Aqueles limites Soft e Hard que podem ser definidos pelo usuário e/ou pelo root são limites genéricos máximos.

Pode verificar também com:

prlimit --pid --nofile

Exemplo:

prlimit --pid 1298 --nofile

RESOURCE DESCRIPTION SOFT HARD UNITS
NOFILE número máximo de arquivos abertos 256 256 arquivos


PID Pulseaudio:

cat /proc/1298/limits

Página anterior     Próxima página

Páginas do artigo
   1. Descritores de Arquivos (File-Descriptors)
   2. Descritores de Arquivos
   3. Swappiness
Outros artigos deste autor

Entendendo o que é URI, URL, URN e conhecendo as diferenças entre POST e GET

Instalar certificado SSL/TLS digital válido gratuito no Linux

Instalação do PAP (PostgreSL, Apache2 e PHP7) no Debian Jessie

Redes de Computadores · IPtables · Endereços IPs - Explicações básicas

Manual traduzido do Squid - Parte 3

Leitura recomendada

Configurando um servidor de FTP no OpenBSD

XGL e Compiz no OpenSuSE 10.2

Criando um servidor FTP acessível fora da LAN com o Proftpd

Criando Redes Locais Virtuais (VLANs) com Linux

AntiX: um Sistema Operacional para computadores antigos

  
Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts