...

Afinação do kernel no alojamento Linux: parâmetros Sysctl em resumo

Afinação do kernel em alojamento Linux traz ganhos de desempenho mensuráveis porque ajusto especificamente os parâmetros sysctl para rede, memória, CPU e segurança. Carrego perfis sem reiniciar e ajusto valores para cargas de trabalho, concorrência e comportamento de E/S para que o Servidor reage rapidamente sob carga e funciona de forma fiável.

Pontos centrais

  • sysctl Controla o comportamento do kernel em tempo de execução
  • Rede otimizar: Backlogs, sockets, TCP
  • Memória trim: Troca, páginas sujas
  • CPU afinação fina: Programador, PIDs
  • Segurança endurecimento sem sobrecarga

O que é o sysctl no alojamento Linux?

Com sysctl Eu leio e altero os parâmetros do kernel em tempo de execução sem compilar o kernel. Os valores são armazenados como arquivos no diretório /proc/sys, como net/ipv4/tcp_max_syn_backlog, e controlam a rede, a memória e a segurança. Para hospedar cargas de trabalho com muitas conexões, o ajuste direto reduz picos de latência e timeouts. Eu faço alterações temporárias com sysctl -w e escrevo perfis permanentes em /etc/sysctl.d/*.conf. Depois carrego tudo com sysctl -system e verifico os registos dmesg e journal para poder reconhecer rapidamente as configurações incorrectas.

Como usar o sysctl com segurança

Antes de efetuar alterações Perfis e documentar os valores reais com sysctl -a para que eu possa reverter a qualquer momento. Primeiro testo os novos valores em VMs de teste com uma carga comparável. Em seguida, aumento os parâmetros passo a passo, monitoro as métricas e ajusto novamente. É assim que evito mortes OOM, quedas de soquete e retransmissões esporádicas. Para configurações reproduzíveis, eu crio um arquivo separado como /etc/sysctl.d/99-hosting.conf e o carrego de maneira controlada.

Testar temporariamente o #
sudo sysctl -w net.core.somaxconn=65535
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=4096

Definir # permanentemente
sudo tee /etc/sysctl.d/99-hosting.conf >/dev/null <<'EOF'
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 4096
vm.swappiness = 10
vm.dirty_ratio = 20
EOF

sudo sysctl --system

Parâmetros de rede que transportam servidores Web

Para muitas ligações simultâneas, aumento somaxconn, para que a lista de pendências do Nginx ou do Apache não transborde. Eu uso net.ipv4.tcp_max_syn_backlog para aumentar a fila de conexões semi-abertas, o que ajuda durante picos de tráfego. Em configurações somente para a web eu geralmente deixo o net.ipv4.ip_forward desligado, com proxies reversos ou gateways eu o ligo. Eu valido as quedas de backlog com ss -s e netstat -s e verifico se as filas de aceitação estão a ficar vazias. Se quiser ir mais fundo no controlo de congestionamento, pode também avaliar algoritmos como o CUBIC ou o BBR; a minha referência a Controlo de congestionamento TCP.

# Exemplo de valores para servidores Web muito frequentados
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.ip_forward = 0

Otimização do armazenamento e da VM para o alojamento de cargas de trabalho

Eu baixo permuta a 10 para que o kernel utilize a RAM durante mais tempo e troque menos. Com vm.dirty_ratio de 15 a 20 por cento, eu limito as páginas sujas para que a carga de escrita não leve a longas explosões de descarga. Para muitos processos, eu defino vm.overcommit_memory para 1 se eu conhecer as aplicações e entender suas reservas. Também monitorizo os acessos à cache da página e a espera de IO para que possa interpretar corretamente os efeitos da cache. Eu dou uma olhada mais profunda no comportamento do cache com este guia para o Cache de página.

# Perfis de armazenamento e de VM
vm.swappiness = 10
vm.dirty_ratio = 20
vm.overcommit_memory = 1

Afinação da CPU e do programador

Com elevada simultaneidade, levanto kernel.pid_max para que muitos processos de trabalho recebam IDs. Para cotas CFS eu ajusto o kernel.sched_cfs_bandwidth_slice_us para evitar fatias muito curtas para serviços com muitas interrupções. Eu verifico os comprimentos das filas de execução, trocas de contexto e tempos de roubo, especialmente em hosts compartilhados. Se eu precisar de isolamento de CPU, eu vinculo serviços a núcleos via taskset ou cgroups. Uma introdução à otimização mais profunda do kernel é fornecida por este compacto Desempenho do kernel-Guia.

# Parâmetros do processo e do agendador
kernel.pid_max = 4194304
# Exemplo para fatias mais finas de CFS
kernel.sched_cfs_bandwidth_slice_us = 5000

Parâmetros de segurança sem perda de desempenho

Eu ativo dmesg_restrict, para prevenir que utilizadores sem privilégios leiam os logs do kernel. Eu uso kernel.kptr_restrict para esconder endereços que poderiam ajudar atacantes com exploits. No nível da rede, eu ligo o rp_filter por padrão para evitar falsificação de IP. Essas configurações não custam quase nada de desempenho e fortalecem significativamente a proteção do host. Eu carrego-as no mesmo ficheiro sysctl de forma controlada para que eu permaneça rastreável.

# Fortalecimento via sysctl
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1

Memória intermédia de rede alargada para um rendimento elevado

Para anfitriões com muito tráfego, adapto Tampão TCP para que as ligações rápidas não fiquem penduradas no limite da janela. Eu uso net.ipv4.tcp_rmem e tcp_wmem para definir os tamanhos mínimo, padrão e máximo. net.core.optmem_max e net.core.netdev_max_backlog ajudam a absorver rajadas curtas de forma limpa. Eu monitoro retransmissões, desenvolvimento de cwnd e níveis de preenchimento de buffer antes de aumentar os valores ainda mais. Essas etapas aumentam a taxa de transferência e reduzem visivelmente as flutuações de latência em links 10G modernos.

Memória intermédia de rede alargada #
net.core.optmem_max = 81920
net.core.netdev_max_backlog = 3000
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

Prática: Da base de referência ao lucro mensurável

Começo cada afinação com um Linha de base e documentar valores-chave como a latência, o débito e a taxa de erro do P95. Em seguida, altero alguns parâmetros, carrego o perfil e meço novamente com ab, wrk ou sysbench. Se a latência diminuir, registo a alteração; se aumentar, reverto-a. É assim que construo um perfil de alojamento que corresponde à minha aplicação. Finalmente, verifico novamente sob carga de produção antes de deixar os valores permanentes.

# Guardar o estado atual
sysctl -a > /root/sysctl-baseline.txt

# Ver parâmetros de rede
sysctl -a | grep -E 'net\.core|net\.ipv4'

# Recarregar perfis
sysctl --system

Tabela de comparação: Perfil padrão vs. perfil de alojamento

O seguinte Tabela apresenta valores iniciais práticos que utilizo frequentemente. Os valores dependem da carga de trabalho, da rede e do hardware. Começo com estes valores, verifico as métricas e ajusto-os passo a passo. Se houver problemas, volto aos valores predefinidos e aumento-os novamente em pequenos passos. Desta forma, minimizo os riscos e obtenho resultados consistentes.

Parâmetros Padrão Perfil de alojamento Benefício
net.core.somaxconn 128 65535 Ligações mais aceites
net.ipv4.tcp_max_syn_backlog 1024 4096 Menos gotas com picos
vm.swappiness 60 10 Menos trocas sob carga
kernel.pid_max 32768 4194304 Mais processos/trabalhadores possíveis
vm.dirty_ratio 30 20 Escrita mais uniforme

Evitar erros comuns e controlo

Não utilizo Valores extremos, porque podem levar a timeouts, OOM kills ou perda de pacotes. Eu testo as mudanças em etapas, cada uma com uma métrica clara e uma curta fase de observação. Os indicadores críticos são o comprimento da fila de aceitação, as retransmissões TCP, a latência P95, a espera IO e a troca de entrada/saída. Utilizo agentes leves e painéis de controlo para monitorizar, de modo a poder reconhecer rapidamente as tendências. Após as actualizações do kernel, verifico se os perfis sysctl ainda são válidos e recarrego-os, se necessário.

Persistência, sequência e distribuições

Para garantir que os perfis permaneçam reproduzíveis, eu observo a sequência de carregamento em /etc/sysctl.d: Os ficheiros são processados lexicograficamente. Eu atribuo deliberadamente prefixos como 60-... ou 99-... para garantir que o meu perfil de alojamento sobrepõe-se a outras predefinições. As diferenças entre distribuições (Debian/Ubuntu vs. RHEL/Alma) normalmente só afectam caminhos e valores por omissão; sysctl -system carrega sempre /etc/sysctl.conf, /etc/sysctl.d/*.conf e ficheiros do fornecedor se aplicável. Depois de grandes actualizações do sistema, verifico com sysctl -system -o (funcionamento a seco dependendo da versão) ou comparo a configuração efectiva carregada com o meu modelo para evitar surpresas.

# Exemplo: assegurar uma sequência limpa
sudo ls -1 /etc/sysctl.d
10-vendor.conf
50-defaults.conf
99-hosting.conf # sobrescreve tudo antes dele

# efetivamente difere os valores carregados
sysctl -a > /root/sysctl-after.txt
diff -u /root/sysctl-baseline.txt /root/sysctl-after.txt | less

Ciclo de vida do TCP e gestão de portas

Sob carga pesada, são criadas muitas ligações de curta duração. Eu coloco ip_local_port_range para que as ligações de saída (por exemplo, de proxies) não fiquem presas no limite de portas efémeras. tcp_fin_timeout controla o tempo de permanência das tomadas no FIN-WAIT-2. Com um Manter vivo-Eu reduzo as sessões mortas mais rapidamente sem cortar agressivamente as conexões. TIME_WAIT é normal e protege contra pacotes atrasados; eu não o reduzo cegamente. tcp_tw_reuse ajuda principalmente em hosts clientes, em servidores puros geralmente fica desligado. Deixo os carimbos de data/hora e o SACK activados, uma vez que melhoram o desempenho e a robustez.

# Intervalo de portas e ciclo de vida do TCP
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
# Cuidado com tcp_tw_reuse: útil apenas para carga de clientes de saída
# net.ipv4.tcp_tw_reuse = 1

Manter o IPv6 e as tabelas de vizinhança estáveis

Atualmente, muitos anfitriões transportam tráfego de pilha dupla. Optimizo as tabelas ARP/ND para que não haja mensagens de „neighbour table overflow“, especialmente em proxies ou nós com muitos pares. O gc_thresh-Defino limiares para corresponder à matriz de ligação. Deixo as opções ICMPv6 e router add restritivas para servidores, para que não sejam incluídas rotas indesejadas. Para IPv4, também presto atenção à recolha de lixo ARP para que as entradas envelheçam atempadamente mas não desapareçam demasiado cedo.

Tabelas de vizinhança #: limiares mais generosos
net.ipv4.neigh.default.gc_thresh1 = 1024
net.ipv4.neigh.default.gc_thresh2 = 4096
net.ipv4.neigh.default.gc_thresh3 = 8192

net.ipv6.neigh.default.gc_thresh1 = 1024
net.ipv6.neigh.default.gc_thresh2 = 4096
net.ipv6.neigh.default.gc_thresh3 = 8192

# ARP/ND-Aging conservador
net.ipv4.neigh.default.gc_stale_time = 60

Pensar em descritores de ficheiros e backlogs em conjunto

Um estrangulamento frequente são Descritores de ficheiros. Se as aplicações têm milhares de sockets, fs.file-max (em todo o sistema) e ulimit/nofile (por serviço) encaixam-se. somaxconn aumenta a fila de listagem, mas só ajuda se o próprio servidor web tiver permissão para abrir mais FDs e a taxa de aceitação for alta o suficiente. Eu certifico-me de que os limites do sistema e do serviço estão sincronizados, caso contrário ocorrem estrangulamentos artificiais apesar dos „grandes“ backlogs do kernel.

# Permitir mais FDs em todo o sistema
fs.file-max = 2097152

# Lado do serviço (exemplo de unidade systemd)
# [Serviço]
# LimitNOFILE=1048576

Amortecer as cargas de trabalho UDP/QUIC

Utilizar DNS, syslog, telemetria e QUIC (HTTP/3) UDP. Aqui eu dimensiono os buffers globais do soquete e os limites de memória específicos do UDP. Para cargas UDP grandes e com rajadas (como gateways de telemetria), isso evita quedas no caminho de receção. Eu monitoro os contadores de erro com ss -u -a e netstat -su e gradualmente ajusto os máximos. Para o QUIC, net.core.rmem_max/wmem_max também é relevante, já que as pilhas de espaço do usuário frequentemente atingem esses limites via setsockopt.

Buffer e limites UDP do #
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.ipv4.udp_mem = 98304 131072 262144
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192

Especificar o writeback sujo: Bytes em vez de percentagens

Em sistemas com muita RAM, os valores percentuais podem levar a grandes descargas repentinas. Portanto, eu prefiro usar vm.dirty_background_bytes e vm.dirty_bytes, para definir limites superiores absolutos. Isto estabiliza a taxa de escrita e suaviza as latências, especialmente com HDDs ou cargas de trabalho mistas. Também considero vm.min_free_kbytes moderadamente para que o kernel tenha memória livre suficiente para as alocações burst.

Exemplo #: limites sujos absolutos (aprox. 1G de fundo, 4G de disco rígido)
vm.dirty_background_bytes = 1073741824
vm.dirty_bytes = 4294967296
vm.min_free_kbytes = 65536

Distribuir a carga de RPS/RFS e IRQ da rede

Em altas taxas de PPS, um único núcleo de CPU pode ficar pendurado no NIC-IRQ. Eu uso o Receive Packet Steering (RPS) e, se necessário, o Receive Flow Steering (RFS) para distribuir o processamento de pacotes entre vários núcleos. Globalmente, eu defino net.core.rps_sock_flow_entries, A alocação real ocorre por fila via sysfs. Isso reduz os hotspots da CPU, melhora a localidade do cache e reduz os picos de latência. Em combinação com net.core.netdev_max_backlog, isso resulta em um pipeline mais robusto.

# Entradas de fluxo globais para RPS
net.core.rps_sock_flow_entries = 32768

# Nota: Ajuste por fila via /sys/class/net//queues/rx-*/rps_cpus
# e rps_flow_cnt, dependendo da placa de rede e do número de filas.

Contentores, namespaces e VMs

Os contentores contêm muitos net.*-Valores namespaced e pode aplicar-se por espaço de nomes de rede. Portanto, eu documento se estou personalizando a rede do host ou do pod/contêiner. Os orquestradores geralmente permitem apenas uma lista segura de sysctls; valores como kernel.pid_max permanecem no lado do host. Nas VMs, eu verifico quais NICs virtuais e offloads estão ativos (virtio, ENA), porque offloads e MTU têm um forte impacto nos requisitos de buffer e desenvolvimento de cwnd. Os hosts bare-metal com NUMA pesado se beneficiam da desativação de vm.zone_reclaim_mode e disposição deliberada da afinidade CPU/IRQ.

# Evitar efeito secundário NUMA
vm.zone_reclaim_mode = 0

Visão geral dos firewalls Conntrack e stateful

Se o host for executado como um NAT/firewall ou hospedar muitos contêineres com NAT de saída, eu dimensiono o nf_conntrack-tabela. As tabelas de hash demasiado pequenas geram quedas e latências elevadas durante as varreduras de tabelas. Eu meço a utilização com o nstat e olho para „esperado“ vs. „em uso“. Para servidores web puros sem NAT, o conntrack é frequentemente pouco crítico ou mesmo desativado; em gateways, deve ser incluído no pacote de afinação.

Tamanho da via de comunicação # (apenas se for utilizada ativamente!)
net.netfilter.nf_conntrack_max = 1048576

Robustez contra ataques e anomalias

Ajuda com o tráfego de bots e análises tcp_syncookies e opções conservadoras de ICMP/redireccionamento. Os Syncookies salvam o aperto de mão no caso de filas SYN transbordantes sem limitar excessivamente o tráfego legítimo. Desabilito redirecionamentos e rotas de origem em servidores que não devem ser roteados. Estas medidas de reforço são leves e complementam os mecanismos de proteção mencionados acima.

# Defesa contra inundações SYN e comportamento de encaminhamento conservador
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

Aprofundar a prática da medição: O que verifico regularmente

Para obter resultados reproduzíveis, meço consistentemente antes e depois das alterações. No lado da rede, uso ss -s, ss -ti, nstat e netstat -s para ver comprimentos de fila, retransmissões e estatísticas de saque. Do lado da memória I/O, vmstat, iostat e pidstat ajudam a categorizar dirty flushes, trocas de contexto e tempos de espera da CPU. Eu também olho para os testes de carga:

  • Fila de aceitação (LISTEN) e fila SYN: abandono vs. transbordos
  • Pacing/throughput por ligação e desenvolvimento de cwnd
  • Latências P95/99 na comparação A/B, em vez de apenas média
  • Taxa de entrada/saída de swap e taxa de acerto da cache de páginas
  • Distribuição da carga de IRQ e comprimentos de fila de execução por CPU
Verificações rápidas do estado do #
ss -s
netstat -s | egrep 'listen|SYN|retran|dropped'
vmstat 1 10
pidstat -w -u -r 1 5

Exemplo: Perfil de alojamento consolidado

Para começar, combino valores básicos e alargados num único ficheiro. Depois, aumento em pequenos passos, cada um com pontos de medição claros. Os valores seguintes são um ponto de partida conservador mas de elevado desempenho para servidores Web e proxies ocupados.

sudo tee /etc/sysctl.d/99-hosting.conf >/dev/null <<'EOF'
# Noções básicas de rede
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 4096
net.core.netdev_max_backlog = 3000
net.core.optmem_max = 81920

Buffers e portas TCP do #
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5

# UDP/QUIC
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.ipv4.udp_mem = 98304 131072 262144
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192

# Tabelas de vizinhança
net.ipv4.neigh.default.gc_thresh1 = 1024
net.ipv4.neigh.default.gc_thresh2 = 4096
net.ipv4.neigh.default.gc_thresh3 = 8192
net.ipv6.neigh.default.gc_thresh1 = 1024
net.ipv6.neigh.default.gc_thresh2 = 4096
net.ipv6.neigh.default.gc_thresh3 = 8192
net.ipv4.neigh.default.gc_stale_time = 60

Segurança #
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

# Memória/VM
vm.swappiness = 10
vm.dirty_ratio = 20
vm.dirty_background_bytes = 1073741824
vm.dirty_bytes = 4294967296
vm.min_free_kbytes = 65536
vm.overcommit_memory = 1
vm.zone_reclaim_mode = 0

CPU/Processos do #
kernel.pid_max = 4194304
kernel.sched_cfs_bandwidth_slice_us = 5000

# RPS
net.core.rps_sock_flow_entries = 32768

# FDs
fs.file-max = 2097152
EOF

sudo sysctl --system

Resumo: Tuning como um processo recorrente

Direcionado Afinação do kernel com o sysctl tem efeitos claros no alojamento: tempos de resposta mais curtos, valores de débito mais elevados e serviços constantes. Começo com noções básicas de rede, como somaxconn e tcp_max_syn_backlog, depois trato da memória com swappiness e dirty_ratio. Depois optimizo PIDs e schedulers e fortaleço a máquina com dmesg_restrict, kptr_restrict e rp_filter. Meço todas as alterações, documento-as e mantenho-me atento às métricas. Passo a passo, crio um perfil que serve as minhas cargas de trabalho de forma eficiente e tem reservas para picos de tráfego.

Artigos actuais