Ajustando os parâmetros de roteamento IP do Linux - secret_interval e tcp_mem

Ajustando os parâmetros de roteamento IP do Linux - secret_interval e tcp_mem

Tivemos um pequeno problema de failover com uma de nossas VMs HAProxy hoje. Quando investigamos, descobrimos o seguinte:

26 de janeiro 07:41:45 kernel haproxy2: [226818.070059] __ratelimit: 10 retornos de chamada suprimidos
26 de janeiro 07:41:45 kernel haproxy2: [226818.070064] Sem memória de soquete
26 de janeiro 07:41:47 kernel haproxy2: [226819.560048] Sem memória de soquete
26 de janeiro 07:41:49 kernel haproxy2: [226822.030044] Sem memória de soquete

O que, poresse link, aparentemente tem a ver com configurações padrão baixas para net.ipv4.tcp_mem. Então, nós os aumentamos em 4x em relação aos padrões (este é o Ubuntu Server, não tenho certeza se o sabor do Linux é importante):

os valores atuais são: 45984 61312 91968
os novos valores são: 183936 245248 367872

Depois disso, começamos a ver uma mensagem de erro bizarra:

26 de janeiro 08:18:49 kernel haproxy1: [2291.579726] Cadeia de hash de rota muito longa!
26 de janeiro 08:18:49 kernel haproxy1: [2291.579732] Ajuste seu secret_interval!

Shh..é um segredo!!

Aparentemente, isso tem a ver com /proc/sys/net/ipv4/route/secret_intervalo padrão 600 e os controleslimpeza periódica do cache de rota

O secret_intervalinstrui o kernel com que frequência eliminar TODAS as entradas de hash de rota, independentemente de quão novas/antigas elas sejam. Em nosso ambiente, isso geralmente é ruim. A CPU estará ocupada reconstruindo milhares de entradas por segundo sempre que o cache for limpo. No entanto, configuramos isso para ser executado uma vez por dia para evitar vazamentos de memória (embora nunca tenhamos tido um).

Embora estejamos felizes em reduzir isso,parece estranho recomendar descartar todo o cache de rota em intervalos regulares, em vez de simplesmente retirar os valores antigos do cache de rota com mais rapidez.

Após alguma investigação, descobrimos /proc/sys/net/ipv4/route/gc_elasticityqual parece ser a melhor opção para manter o tamanho da tabela de rotas sob controle:

gc_elasticitypode ser melhor descrito como a profundidade média do bucket que o kernel aceitará antes de começar a expirar as entradas de hash de rota. Isso ajudará a manter o limite superior de rotas ativas.

Ajustamos a elasticidade de 8 para 4, na esperança de que o cache de rota se reduza de forma mais agressiva.Isso secret_intervalnão parece correto para nós. Mas há um monte de configurações e não está claro qual é realmente o caminho certo a seguir aqui.

  • /proc/sys/net/ipv4/route/gc_elasticity (8)
  • /proc/sys/net/ipv4/route/gc_interval (60)
  • /proc/sys/net/ipv4/route/gc_min_interval (0)
  • /proc/sys/net/ipv4/route/gc_timeout (300)
  • /proc/sys/net/ipv4/route/secret_interval (600)
  • /proc/sys/net/ipv4/route/gc_thresh (?)
  • rhash_entries (parâmetro do kernel, padrão desconhecido?)

Não queremos fazer o roteamento do Linuxpior, então temos medo de mexer em algumas dessas configurações.

Alguém pode aconselhar quais parâmetros de roteamento são melhores para ajustar, para uma instância HAProxy de alto tráfego?

Responder1

Nunca encontrei esse problema. No entanto, você provavelmente deve aumentar a largura da tabela hash para reduzir sua profundidade. Usando "dmesg", você verá quantas entradas possui atualmente:

$ dmesg | grep '^IP route'
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)

Você pode alterar esse valor com o parâmetro de linha de comando de inicialização do kernel rhash_entries. Primeiro experimente manualmente e depois adicione-o ao seu lilo.confarquivo ou grub.conf.

Por exemplo:kernel vmlinux rhash_entries=131072

É possível que você tenha uma tabela de hash muito limitada porque atribuiu pouca memória à sua VM HAProxy (o tamanho do hash da rota é ajustado dependendo da RAM total).

Em relação a tcp_mem, tenha cuidado. Suas configurações iniciais me fazem pensar que você estava rodando com 1 GB de RAM, 1/3 dos quais poderiam ser alocados para soquetes TCP. Agora você alocou 367.872 * 4.096 bytes = 1,5 GB de RAM para soquetes TCP. Você deve ter muito cuidado para não ficar sem memória. Uma regra prática é alocar 1/3 da memória para HAProxy e outro 1/3 para a pilha TCP e o último 1/3 para o resto do sistema.

Suspeito que sua mensagem "memória sem soquete" venha das configurações padrão em tcp_rmeme tcp_wmem. Por padrão você tem 64 kB alocados na saída para cada soquete e 87 kB na entrada. Isso significa um total de 300 kB para uma conexão proxy, apenas para buffers de soquete. Adicione a isso 16 ou 32 kB para HAProxy e você verá que com 1 GB de RAM você suportará apenas 3.000 conexões.

Ao alterar as configurações padrão de tcp_rmeme tcp_wmem(parâmetro intermediário), você pode diminuir muito a memória. Obtenho bons resultados com valores tão baixos quanto 4.096 para o buffer de gravação e 7.300 ou 16.060 pol. tcp_rmem(5 ou 11 segmentos TCP). Você pode alterar essas configurações sem reiniciar, mas elas só serão aplicadas a novas conexões.

Se você preferir não tocar em seusysctlsdemais, o HAProxy mais recente, 1.4-dev8, permite ajustar esses parâmetros da configuração global e por lado (cliente ou servidor).

Espero que isso ajude!

Responder2

Muitas vezes é Out of socket memory errorenganoso. Na maioria das vezes, em servidores voltados para a Internet, isso acontecenãoindicar qualquer problema relacionado à falta de memória. Como expliquei com muito mais detalhes emuma postagem no blog, o motivo mais comum é o número de soquetes órfãos. Um soquete órfão é um soquete que não está associado a um descritor de arquivo. Em certas circunstâncias, o kernel emitirá o Out of socket memory errormesmo que você esteja 2x ou 4x longe do limite ( /proc/sys/net/ipv4/tcp_max_orphans). Isso acontece com frequência em serviços voltados para a Internet e é perfeitamente normal. O curso de ação correto neste caso é ajustar tcp_max_orphanspara pelo menos 4x o número de órfãos que você normalmente vê em seu pico de tráfego.

Não dê ouvidos a nenhum conselho que recomende afinação tcp_memou tcp_rmemou tcp_wmema menos que vocêrealmentesabe o que você está fazendo. Aqueles que dão esses conselhos normalmente não o fazem. O vodu deles geralmente é errado ou inadequado para o seu ambiente e não resolverá o seu problema. Pode até piorar as coisas.

Responder3

Ajustamos alguns desses parâmetros regularmente. Nosso padrão para plataformas de negociação de alto rendimento e baixa latência é:

net.ipv4.tcp_rmem = 4096 16777216 33554432
net.ipv4.tcp_wmem = 4096 16777216 33554432
net.ipv4.tcp_mem = 4096 16777216 33554432
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.core.netdev_max_backlog=30000
net.core.netdev_max_backlog=30000

informação relacionada