...

Equilíbrio de IRQs de servidor e desempenho de rede para alojamento de alta carga

A carga elevada da rede é determinada pelo processamento eficiente de IRQ do servidor sinais: Se você distribuir as interrupções de forma inteligente entre os núcleos da CPU, você reduz a latência e evita quedas. Neste guia, mostrarei como combinar balanceamento de IRQ, RSS/RPS e afinidade de CPU de forma prática para tornar sustentável a hospedagem de alta carga. eficaz para funcionar.

Pontos centrais

  • Distribuição de IRQ evita pontos de acesso em núcleos individuais da CPU.
  • Fila múltipla mais RSS/RPS paraleliza o processamento de pacotes.
  • Atenção NUMA reduz o acesso e a latência entre nós.
  • Regulador da CPU e a fixação de threads suavizam os tempos de resposta.
  • Monitorização Verifica os pps, as latências, as quedas e a utilização do núcleo.

Breve explicação dos IRQs: Por que eles controlam a carga da rede

Para cada pacote de entrada, a placa de rede informa via IRQ, que o trabalho está pendente, caso contrário o kernel teria de sondar ativamente. Se a atribuição permanecer num núcleo, a sua utilização aumenta, enquanto outros núcleos não utilizado permanecem. É exatamente nesta altura que as latências aumentam, os buffers do anel RX ficam cheios e os controladores começam a descartar os pacotes. Eu distribuo as interrupções pelos núcleos adequados para manter o processamento de pacotes uniforme e previsível. Isso alivia os gargalos, suaviza os tempos de resposta e mantém as perdas de pacotes em um nível mínimo.

Balanceamento de IRQ e afinidade de CPU no Linux

O serviço equilíbrio do Iraque distribui as interrupções dinamicamente, analisa a carga e muda as afinidades automaticamente ao longo do tempo. Para perfis de carga extremos, eu defino as afinidades manualmente via /proc/irq//smp_affinity e ligam as pistas especificamente aos núcleos do mesmo NUMA-nós. Esta combinação de ajuste automático e fino ajuda-me a processar cargas de base e picos de forma limpa. Uma introdução aprofundada ao Tratamento de interrupções e otimização da CPU Utilizo-os para me ajudar no meu planeamento. Isso continua a ser importante: Eu sempre relaciono a topologia do hardware, a distribuição de IRQs e os threads de aplicativos entre si.

Utilização prática de NICs com várias filas de espera, RSS e RPS

As placas de rede modernas fornecem várias filas RX/TX, cada fila acciona o seu próprio IRQs, e o Receive Side Scaling (RSS) distribui os fluxos para os núcleos. Se não houver filas de hardware suficientes, eu adiciono Receive Packet Steering (RPS) e Transmit Packet Steering (XPS) ao kernel para Paralelismo. Com ethtool -L ethX combinado N Ajusto o número da fila para o número do núcleo do nó NUMA associado. Verifico com ettool -S e nstat, se ocorrem quedas, sondagens de ocupado ou picos de pps elevados. Para uma suavização mais fina da carga, também utilizo Coalescência de interrupções no planeamento, para que a placa de rede não gere demasiados IRQs individuais.

A tabela seguinte mostra os componentes centrais e os comandos típicos que utilizo para uma configuração coerente:

Bloco de construção Objetivo Exemplo Nota
equilíbrio do Iraque Distribuição automática systemctl enable --now irqbalance Ponto de partida para cargas de trabalho mistas
Afinidade Corrige a fixação echo mask > /proc/irq/XX/smp_affinity Observar a atribuição NUMA
Tacos Mais paralelismo ethtool -L ethX combinado N Correspondência com núcleos de nós
RSS/RPS Distribuição do fluxo sysfs: rps_cpus/rps_flow_cnt Útil para um pequeno número de filas de espera de NIC
XPS Núcleos de trajetória TX ordenados sysfs: xps_cpus Evita o desgaste da cache

Utilização sensata do balanceamento automático de IRQ

Para servidores de alojamento mistos, é muitas vezes suficiente ativar equilíbrio do Iraque, porque o daemon reconhece constantemente as mudanças de carga. Verifico o estado através de systemctl status irqbalance e dar uma vista de olhos em /proc/interrupções, para ver a distribuição por fila e núcleo. Se as latências aumentarem em picos, defino núcleos de teste que processam principalmente interrupções e comparo os valores medidos antes e depois da alteração. Eu mantenho a configuração simples, para que as auditorias e reversões posteriores sejam rápidas. Só quando os padrões são claros é que me aprofundo na fixação.

Afinidade manual da CPU para um controlo máximo

Com taxas de pps muito elevadas, coloco filas de RX em núcleos selecionados do mesmo NUMA-e separo deliberadamente os threads de aplicação deles. Eu isolo núcleos individuais para interrupções, executo trabalhadores em núcleos vizinhos e presto atenção estrita à localidade do cache. Desta forma, reduzo os acessos entre nós e minimizo as dispendiosas mudanças de contexto no hot path. Para obter resultados reproduzíveis, documentei claramente as máscaras de IRQ, a atribuição de filas e a afinidade de thread dos serviços. Essa clareza mantém os tempos de execução dos pacotes constante e reduz os valores anómalos.

Coordenação limpa da otimização da CPU e das aplicações

Eu coloquei o Regulador da CPU frequentemente definido como „desempenho“ porque as alterações de relógio aumentam os saltos de latência. Eu vinculo processos críticos como Nginx, HAProxy ou bancos de dados a núcleos que estão próximos aos núcleos IRQ, ou eu os separo deliberadamente se o perfil de cache exigir isso. Continua a ser importante limitar as alterações de contexto e manter o kernel atualizado para que as optimizações na pilha de rede tenham efeito. Meço os efeitos de cada mudança em vez de fazer suposições e adapto-me passo a passo. Isso resulta em uma configuração que funciona sob carga previsível reage.

Configurar corretamente a monitorização e a medição

Sem valores medidos, a afinação continua a ser um jogo de adivinhação, por isso vou começar com sar, mpstat, vmstat, nstat, ss e ettool -S. Para testes de carga estruturados, utilizo iperf3 e analiso o débito, os pps, a latência, as retransmissões e a utilização do núcleo. Registo tendências a longo prazo utilizando sistemas de monitorização padrão para reconhecer padrões como picos noturnos, janelas de backup ou campanhas. Se quiser compreender o percurso dos dados de forma holística, beneficia de uma visão do Pipeline de processamento de pacotes do IRQ da placa de rede para o espaço do utilizador. Somente a combinação desses sinais mostra se o balanceamento de IRQ e a afinidade alcançaram o efeito desejado. Efeito trazer.

Compreender a NAPI, Softirqs e ksoftirqd

Para gerir os picos de latência com cargas elevadas de pps, tenho em conta a NAPI-e a interação entre IRQs rígidos e IRQs suaves. Após o primeiro IRQ de hardware, a NAPI recupera vários pacotes da fila de RX em modo de pesquisa para evitar tempestades de IRQ. Se os IRQs soft não forem processados prontamente, eles são movidos para ksoftirqd/N Threads que só funcionam com prioridade normal - uma razão clássica para aumentar as latências de cauda. Eu observo /proc/softirqs e /proc/net/softnet_stat; um elevado „tempo de espera“ indicam que o orçamento é demasiado apertado. Com sysctl -w net.core.netdev_budget_usecs=8000 e sysctl -w net.core.netdev_budget=600 Aumento o tempo de processamento por pesquisa de NIC e o orçamento de pacotes como um teste. Importante: Aumento os valores gradualmente, meço e verifico se ocorre jitter da CPU ou interferência com threads de aplicativos.

Ajuste fino do hash RSS e da tabela de indirecção

O RSS distribui fluxos para filas através da tabela de indirecção (RETA). Verifico a chave de hash e a tabela com ethtool -n ethX rx-flow-hash tcp4 e definir a distribuição simetricamente, se necessário. Com ethtool -X ethX igual N ou especificamente por entrada (ethtool -X ethX hkey ... hfunc toeplitz indir 0:1 1:3 ...), faço corresponder as atribuições aos núcleos preferenciais de um nó NUMA. O objetivo é Aderência do fluxoUm fluxo permanece no mesmo núcleo para que a localidade do cache e a retenção de bloqueios na pilha permaneçam mínimas. Para ambientes com muitos fluxos UDP curtos, eu aumento o rps_flow_cnt por fila de RX para que a distribuição de software tenha baldes suficientes e não crie hotspots. Não me esqueço de que os hashes simétricos ajudam nas topologias ECMP, mas no contexto do servidor, o equilíbrio dos núcleos é o que mais conta.

Seleção sensata de descargas, GRO/LRO e tamanhos de anéis

As descargas de hardware reduzem a carga na CPU, mas podem alterar os perfis de latência. Eu verifico com ethtool -k ethX, se TSO/GSO/UDP_SEG no TX e GRO/LRO estão activos no RX. O GRO agrupa pacotes no kernel e é quase sempre útil para a taxa de transferência; o LRO pode ser problemático em configurações de roteamento ou filtragem e é melhor deixá-lo de fora. Para APIs críticas em termos de latência, eu testo uma agregação GRO mais pequena (ou temporariamente desligada) se as latências p99 dominarem. Eu também ajusto o tamanho dos anéis via ethtool -G ethX rx 1024 tx 1024Anéis maiores interceptam rajadas, mas aumentam a latência em caso de congestionamento; anéis demasiado pequenos conduzem a rx_missed_errors. Baseio-me em valores medidos a partir de ettool -S (por exemplo. rx_no_buffer_count, rx_dropped) e concordar com BQL (limites de filas de bytes, automáticos no lado do kernel) para que as filas TX não sejam sobrecarregadas.

Virtualização: IRQs em VMs e no hipervisor

Em configurações virtualizadas, controlo a distribuição física de NIC no anfitrião e defino Equilíbrio de IRQ claramente. As VMs obtêm vCPUs suficientes, mas eu evito o comprometimento excessivo cego para que os atrasos de agendamento não aumentem a latência. Drivers paravirtualizados modernos, como virtio-net ou vmxnet3, me fornecem os melhores caminhos para altas taxas de pps. Dentro da VM, verifico novamente a afinidade e a contagem de filas para que o convidado não se torne um gargalo. É crucial ter uma visão consistente do host e do convidado para que todo o caminho de dados verdadeiro.

Aprofundar a virtualização: SR-IOV, vhost e OVS

Para taxas de pps muito elevadas, utilizo o hipervisor SR-IOVEu vinculei funções virtuais (VFs) da NIC física diretamente às VMs e as fixei nos núcleos dos nós NUMA apropriados. Isso ignora partes da pilha do host e reduz a latência. Onde o SR-IOV não se encaixa, eu presto atenção a vhost-net e fixar os threads do vhost, como trabalhadores de aplicativos e núcleos de IRQ, para que não ocorram saltos entre NUMAs. Em configurações de sobreposição ou comutação, avalio os custos adicionais da ponte Linux ou do OVS; para perfis extremos, só uso o OVS-DPDK se o esforço operacional justificar a vantagem mensurável. O mesmo se aplica aqui: eu meço pps, latência e distribuição de CPU antes de tomar decisões, não depois.

Sondagem de ocupação e afinação do espaço do utilizador

Para serviços críticos em termos de latência Sondagem ocupada reduzir o jitter. Activei o seguinte como teste sysctl -w net.core.busy_read=50 e net.core.busy_poll=50 (microssegundos) e definir a opção de socket SO_BUSY_POLL seletivamente para sockets afetados. O espaço do usuário então sonda pouco antes de bloquear e pega os pacotes antes que eles se movam mais profundamente nas filas. Isso custa tempo de CPU, mas geralmente fornece latências p99 mais estáveis. Eu mantenho os valores baixos, monitoro a utilização do núcleo e só combino polling ocupado com afinidade clara de thread e um regulador de CPU fixo, caso contrário os efeitos se cancelam.

Resumo dos custos do filtro de encomendas, do Conntrack e do eBPF

A firewall e o NAT fazem parte do percurso dos dados. Por conseguinte, verifico o nftables/iptables-e arrumo as regras mortas ou as cadeias profundas. Em configurações ocupadas, ajusto o tamanho da tabela do Conntrack (nf_conntrack_max, hash bucket number) ou desativar o Conntrack especificamente para fluxos sem estado. Se forem utilizados programas eBPF (XDP, tc-BPF), meço os seus custos de tempo de execução por hook e dou prioridade ao „early drop/redirect“ para aliviar os caminhos dispendiosos. É importante ter uma responsabilidade clara: ou a otimização tem efeito na descarga da placa de rede, no programa eBPF ou na pilha clássica - a duplicação só aumenta a latência.

Isolamento da CPU e núcleos de manutenção

Para uma latência absolutamente determinística, guardo o trabalho de fundo em CPUs de limpeza off. Os parâmetros do kernel, tais como nohz_full=, rcu_nocbs= e irqaffinity= ajudam a manter os núcleos dedicados em grande parte livres de manipulação de ticks, retornos de chamada RCU e IRQs externos. Eu isolo um conjunto de núcleos para os trabalhadores da aplicação e outro para IRQs e softirqs; os serviços do sistema e os temporizadores são executados em núcleos separados. Isso garante perfis de cache limpos e reduz os efeitos de preempção. O hyper-threading pode aumentar o jitter em casos individuais; testo se a sua desativação por par de núcleos suaviza as latências p99 antes de tomar uma decisão global.

Manual de diagnóstico e antipadrões típicos

Quando ocorrem quedas ou picos de latência, adoto uma abordagem estruturada: 1) /proc/interrupções Verificar se a distribuição é desigual. 2) ettool -S em quedas RX/TX, erros FIFO, rx_no_buffer_count verificar. 3) /proc/net/softnet_stat para „tempo de espera" ou "gotas“. 4) mpstat -P TODOS e topo para a atividade ksoftirqd. 5) Métricas da aplicação (número de ligações activas, retransmissões com ss -ti). Anti-padrões que evito: enormes anéis de RX (congestionamento oculto), ativação/desativação selvagem de offloads sem medição, mistura de afinidades fixas com irqbalance agressivo, ou RPS e RSS em simultâneo sem uma arquitetura alvo clara. Cada alteração é objeto de uma medição antes/depois de uma comparação e de um breve protocolo.

Exemplos de conceitos para alojamento web e APIs

Servidor de alojamento web clássico

Para muitos sítios Web pequenos, ativo equilíbrio do Iraque, Configuro várias filas e selecciono o regulador de desempenho. Meço as latências L7 durante os picos e presto atenção aos picos de pps, que ocorrem principalmente com TLS e HTTP/2. Se as filas de hardware não forem suficientes, adiciono RPS para distribuição adicional ao nível do software. Este ajuste mantém os tempos de resposta constante, mesmo que a utilização global da capacidade pareça moderada. Controlos regulares de /proc/interrupções mostrar-me se os núcleos individuais estão a inclinar-se.

Proxy reverso de alta carga ou gateway de API

Para frontends com um grande número de conexões, eu fixo filas RX finamente em núcleos definidos e posiciono proxy workers em núcleos próximos. Eu tomo uma decisão consciente sobre se o irqbalance permanece ativo ou se a fixação fixa fornece resultados mais claros. Se não houver filas suficientes, selecciono especificamente RPS/XPS e calibro Coalescência, para evitar tempestades de IRQs. Isto permite-me obter uma baixa latência a uma taxa de pps muito elevada e manter as latências finais sob controlo. A documentação de cada alteração facilita as auditorias subsequentes e mantém o comportamento previsível.

Escolha do fornecedor e critérios de hardware

Presto atenção aos NICs com Fila múltipla, latência fiável na espinha dorsal e versões actualizadas do kernel da plataforma. A topologia equilibrada da CPU e a separação NUMA clara impedem que as interrupções de rede cheguem a zonas de memória remotas. Para projectos com taxas de pps elevadas, a escolha da infraestrutura honra cada hora de afinação, porque o hardware fornece reservas. Em comparações práticas, tenho trabalhado bem com fornecedores que divulgam perfis de desempenho e fornecem predefinições compatíveis com IRQ, como fornecedores como webhoster.de. Essas configurações permitem-me usar o balanceamento de IRQ, RSS e afinidade de forma eficaz e minimizar os tempos de resposta. estreito para segurar.

Procedimento passo-a-passo para a sua própria afinação

Passo 1: Determino o estado atual com iperf3, sar, mpstat, nstat e ettool -S, para que eu tenha valores iniciais claros. Passo 2: Se o irqbalance não estiver em execução, ativo o serviço, aguardo sob carga e comparo a latência, os pps e as quedas. Passo 3: Ajusto o número da fila e a configuração RSS para os núcleos do nó NUMA associado. Passo 4: Defino o regulador da CPU para „desempenho“ e atribuo serviços centrais aos núcleos apropriados. Passo 5: Só então eu ajusto a afinidade manual e a fixação NUMA se os valores medidos ainda mostrarem gargalos. Passo 6: Verifico as tendências ao longo dos dias para classificar de forma fiável os picos de eventos, os backups ou os picos de marketing.

Brevemente resumido

Eficaz Equilíbrio de IRQ distribui o trabalho de rede entre núcleos adequados, reduz latências e evita quedas em altas taxas de pps. Em combinação com NICs de filas múltiplas, RSS/RPS, um regulador de CPU adequado e afinidade de thread limpa, eu utilizo a pilha de rede de forma confiável. Valores medidos a partir de ettool -S, nstat, sar e iperf3 me conduzam passo a passo ao meu objetivo em vez de andar às voltas no escuro. Se pensar na topologia NUMA, na fixação de IRQ e na colocação de aplicações em conjunto, pode manter os tempos de resposta a um nível mínimo. baixo - mesmo durante picos de carga. Isto significa que o alojamento de alta carga permanece visivelmente responsivo sem queimar reservas desnecessárias de CPU.

Artigos actuais