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

30

Tivemos um pequeno problema de failover com uma de nossas VMs HAProxy hoje. Quando cavamos, descobrimos isso:

Jan 26 07:41:45 haproxy2 kernel: [226818.070059] __ratelimit: 10 callbacks suppressed
Jan 26 07:41:45 haproxy2 kernel: [226818.070064] Out of socket memory
Jan 26 07:41:47 haproxy2 kernel: [226819.560048] Out of socket memory
Jan 26 07:41:49 haproxy2 kernel: [226822.030044] Out of socket memory

Que, por este link , aparentemente tem a ver com configurações padrão baixas para net.ipv4.tcp_mem . Então aumentamos 4x a partir de seus padrões (isto é Ubuntu Server, não tenho certeza se o sabor do Linux é importante):

current values are:    45984   61312   91968
new values are:       183936  245248  367872

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

Jan 26 08:18:49 haproxy1 kernel: [ 2291.579726] Route hash chain too long!
Jan 26 08:18:49 haproxy1 kernel: [ 2291.579732] Adjust your secret_interval!

Shh .. é um segredo !!

Isso aparentemente tem a ver com /proc/sys/net/ipv4/route/secret_interval , cujo padrão é 600 e controla o fluxo periódico do cache de rota

The secret_interval instructs the kernel how often to blow away ALL route hash entries regardless of how new/old they are. In our environment this is generally bad. The CPU will be busy rebuilding thousands of entries per second every time the cache is cleared. However we set this to run once a day to keep memory leaks at bay (though we've never had one).

Embora estejamos satisfeitos em reduzir isso, parece estranho recomendar a queda de todo o cache de rota em intervalos regulares , em vez de simplesmente empurrar valores antigos para fora do cache de rota mais rapidamente.

Após algumas investigações, encontramos /proc/sys/net/ipv4/route/gc_elasticity , que parece ser a melhor opção para manter o tamanho da tabela de rotas sob controle:

gc_elasticity can best be described as the average bucket depth the kernel will accept before it starts expiring route hash entries. This will help maintain the upper limit of active routes.

Nós ajustamos a elasticidade de 8 para 4, na esperança de que o cache de rota seja podado de forma mais agressiva. O secret_interval não parece correto para nós. Mas há um monte de configurações e não está claro qual é o caminho certo para ir até aqui.

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

Não queremos tornar o roteamento do Linux pior , por isso 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?

    
por Jeff Atwood 26.01.2010 / 21:41

3 respostas

28

Eu nunca encontrei esse problema. No entanto, você provavelmente deve aumentar a largura da tabela de hash para reduzir sua profundidade. Usando o "dmesg", você verá quantas entradas você tem 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, tente-o manualmente e adicione-o ao seu lilo.conf ou grub.conf .

Por exemplo: kernel vmlinux rhash_entries=131072

É possível que você tenha uma tabela de hash muito limitada, porque você atribuiu pouca memória à sua VM HAProxy (o tamanho de 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 executando com 1 GB de RAM, 1/3 dos quais poderiam ser alocados para soquetes TCP. Agora você alocou 367872 * 4096 bytes = 1,5 GB de RAM para soquetes TCP. Você deve ter muito cuidado para não ficar sem memória. Uma regra é 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.

Eu suspeito que sua mensagem "sem memória de soquete" vem das configurações padrão em tcp_rmem e 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 com proxy, apenas para buffers de soquete. Acrescente a isso 16 ou 32 kB para o HAProxy, e você verá que com 1 GB de RAM você suportará apenas 3000 conexões.

Alterando as configurações padrão de tcp_rmem e tcp_wmem (middle param), você pode ficar muito mais baixo na memória. Eu obtenho bons resultados com valores tão baixos quanto 4096 para o buffer de gravação e 7300 ou 16060 em tcp_rmem (5 ou 11 segmentos TCP). Você pode alterar essas configurações sem reiniciar, mas elas só se aplicam a novas conexões.

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

Espero que isso ajude!

    
por 26.01.2010 / 22:37
8

O Out of socket memory error costuma ser enganoso. Na maioria das vezes, em servidores com acesso à Internet, não indica qualquer problema relacionado à falta de memória. Como expliquei em detalhes muito maiores em uma 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 error mesmo 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 correto de ação nesse caso é ajustar tcp_max_orphans para ser pelo menos 4x o número de órfãos que você normalmente vê com seu tráfego de pico.

Não ouça qualquer recomendação que recomende o ajuste de tcp_mem ou tcp_rmem ou tcp_wmem , a menos que você realmente saiba o que está fazendo. Aqueles que dão esses conselhos normalmente não. Seu voodoo é muitas vezes errado ou inadequado para o seu ambiente e não irá resolver o seu problema. Pode até piorar a situação.

    
por 15.03.2011 / 06:43
-3

Ajustamos alguns desses parâmetros regularmente. Nosso padrão para plataformas de negociação de alta produtividade 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
    
por 26.01.2010 / 23:25