Melhorando o desempenho do TCP em uma rede gigabit com muitas conexões e alto tráfego de pequenos pacotes

36

Estou tentando melhorar minha taxa de transferência TCP em uma "rede gigabit com muitas conexões e alto tráfego de pequenos pacotes". Meu sistema operacional do servidor é Ubuntu 11.10 Server 64bit.

Existem cerca de 50.000 (e crescentes) clientes conectados ao meu servidor através do TCP Sockets (todos na mesma porta).

95% dos meus pacotes têm tamanho de 1-150 bytes (cabeçalho TCP e carga útil). Os 5% restantes variam de 150 a 4096 bytes.

Com a configuração abaixo, o meu servidor pode lidar com tráfego de até 30 Mbps (full duplex).

Você pode, por favor, aconselhar as melhores práticas para ajustar o sistema operacional de acordo com minhas necessidades?

Meu /etc/sysctl.cong é assim:

kernel.pid_max = 1000000
net.ipv4.ip_local_port_range = 2500 65000
fs.file-max = 1000000
#
net.core.netdev_max_backlog=3000
net.ipv4.tcp_sack=0
#
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.somaxconn = 2048
#
net.ipv4.tcp_rmem = 4096 87380 16777216 
net.ipv4.tcp_wmem = 4096 65536 16777216
#
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_mem = 50576   64768   98152
#
net.core.wmem_default = 65536
net.core.rmem_default = 65536
net.ipv4.tcp_window_scaling=1
#
net.ipv4.tcp_mem= 98304 131072 196608
#
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_rfc1337 = 1
net.ipv4.ip_forward = 0
net.ipv4.tcp_congestion_control=cubic
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
#
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192

Aqui estão meus limites:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 193045
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1000000
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) 1000000

[ADICIONADO]

Minhas NICs são as seguintes:

$ dmesg | grep Broad
[    2.473081] Broadcom NetXtreme II 5771x 10Gigabit Ethernet Driver bnx2x 1.62.12-0 (2011/03/20)
[    2.477808] bnx2x 0000:02:00.0: eth0: Broadcom NetXtreme II BCM57711E XGb (A0) PCI-E x4 5GHz (Gen2) found at mem fb000000, IRQ 28, node addr d8:d3:85:bd:23:08
[    2.482556] bnx2x 0000:02:00.1: eth1: Broadcom NetXtreme II BCM57711E XGb (A0) PCI-E x4 5GHz (Gen2) found at mem fa000000, IRQ 40, node addr d8:d3:85:bd:23:0c

[ADICIONADO 2]

ethtool -k eth0
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: on
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off
receive-hashing: off

[ADICIONADO 3]

 sudo ethtool -S eth0|grep -vw 0
 NIC statistics:
      [1]: rx_bytes: 17521104292
      [1]: rx_ucast_packets: 118326392
      [1]: tx_bytes: 35351475694
      [1]: tx_ucast_packets: 191723897
      [2]: rx_bytes: 16569945203
      [2]: rx_ucast_packets: 114055437
      [2]: tx_bytes: 36748975961
      [2]: tx_ucast_packets: 194800859
      [3]: rx_bytes: 16222309010
      [3]: rx_ucast_packets: 109397802
      [3]: tx_bytes: 36034786682
      [3]: tx_ucast_packets: 198238209
      [4]: rx_bytes: 14884911384
      [4]: rx_ucast_packets: 104081414
      [4]: rx_discards: 5828
      [4]: rx_csum_offload_errors: 1
      [4]: tx_bytes: 35663361789
      [4]: tx_ucast_packets: 194024824
      [5]: rx_bytes: 16465075461
      [5]: rx_ucast_packets: 110637200
      [5]: tx_bytes: 43720432434
      [5]: tx_ucast_packets: 202041894
      [6]: rx_bytes: 16788706505
      [6]: rx_ucast_packets: 113123182
      [6]: tx_bytes: 38443961940
      [6]: tx_ucast_packets: 202415075
      [7]: rx_bytes: 16287423304
      [7]: rx_ucast_packets: 110369475
      [7]: rx_csum_offload_errors: 1
      [7]: tx_bytes: 35104168638
      [7]: tx_ucast_packets: 184905201
      [8]: rx_bytes: 12689721791
      [8]: rx_ucast_packets: 87616037
      [8]: rx_discards: 2638
      [8]: tx_bytes: 36133395431
      [8]: tx_ucast_packets: 196547264
      [9]: rx_bytes: 15007548011
      [9]: rx_ucast_packets: 98183525
      [9]: rx_csum_offload_errors: 1
      [9]: tx_bytes: 34871314517
      [9]: tx_ucast_packets: 188532637
      [9]: tx_mcast_packets: 12
      [10]: rx_bytes: 12112044826
      [10]: rx_ucast_packets: 84335465
      [10]: rx_discards: 2494
      [10]: tx_bytes: 36562151913
      [10]: tx_ucast_packets: 195658548
      [11]: rx_bytes: 12873153712
      [11]: rx_ucast_packets: 89305791
      [11]: rx_discards: 2990
      [11]: tx_bytes: 36348541675
      [11]: tx_ucast_packets: 194155226
      [12]: rx_bytes: 12768100958
      [12]: rx_ucast_packets: 89350917
      [12]: rx_discards: 2667
      [12]: tx_bytes: 35730240389
      [12]: tx_ucast_packets: 192254480
      [13]: rx_bytes: 14533227468
      [13]: rx_ucast_packets: 98139795
      [13]: tx_bytes: 35954232494
      [13]: tx_ucast_packets: 194573612
      [13]: tx_bcast_packets: 2
      [14]: rx_bytes: 13258647069
      [14]: rx_ucast_packets: 92856762
      [14]: rx_discards: 3509
      [14]: rx_csum_offload_errors: 1
      [14]: tx_bytes: 35663586641
      [14]: tx_ucast_packets: 189661305
      rx_bytes: 226125043936
      rx_ucast_packets: 1536428109
      rx_bcast_packets: 351
      rx_discards: 20126
      rx_filtered_packets: 8694
      rx_csum_offload_errors: 11
      tx_bytes: 548442367057
      tx_ucast_packets: 2915571846
      tx_mcast_packets: 12
      tx_bcast_packets: 2
      tx_64_byte_packets: 35417154
      tx_65_to_127_byte_packets: 2006984660
      tx_128_to_255_byte_packets: 373733514
      tx_256_to_511_byte_packets: 378121090
      tx_512_to_1023_byte_packets: 77643490
      tx_1024_to_1522_byte_packets: 43669214
      tx_pause_frames: 228

Algumas informações sobre o SACK: Quando desativar o TCP SACK?

    
por Worker 07.02.2012 / 23:10

6 respostas

20

O problema pode ser que você está recebendo muitas interrupções na sua placa de rede. Se Bandwidth não é o problema, frequência é o problema:

  • Aumente os buffers de envio / recebimento na placa de rede

    ethtool -g eth0
    

Irá mostrar as configurações atuais (256 ou 512 entradas). Você provavelmente pode aumentá-las para 1024, 2048 ou 3172. Mais provavelmente não faz sentido. Este é apenas um buffer de anel que só é preenchido se o servidor não conseguir processar os pacotes recebidos com rapidez suficiente.

Se o buffer começar a ser preenchido, o controle de fluxo é um meio adicional de informar ao roteador ou ao switch para diminuir a velocidade:

  • Ative o controle de fluxo de entrada / saída no servidor e as portas de switch / roteador às quais ele está conectado.

    ethtool -a eth0
    

provavelmente mostrará:

Pause parameters for eth0:
Autonegotiate:  on
RX:             on
TX:             on

Verifique / var / log / messages para a configuração atual de eth0. Verifique por algo como:

eth0: Link is up at 1000 Mbps, full duplex, flow control tx and rx

Se você não vir o tx e o rx, seus administradores de rede precisam ajustar os valores no switch / roteador. Na Cisco que está recebendo / transmitindo o controle de fluxo.

Cuidado: A alteração desses valores reduzirá o seu link por um tempo muito curto (menos de 1 segundo).

  • Se tudo isso não ajudar - você também pode diminuir a velocidade da placa de rede para 100 MBit (faça o mesmo nas portas do switch / roteador)

    ethtool -s eth0 autoneg off && ethtool -s eth0 speed 100
    

Mas no seu caso eu diria - aumentar os buffers de recepção no buffer de anel do NIC.

    
por 11.02.2012 / 23:45
4

A seguir pode não ser a resposta definitiva, mas vai certamente apresentar algumas ideias

Tente adicioná-las ao sysctl.conf

##  tcp selective acknowledgements. 
net.ipv4.tcp_sack = 1
##enable window scaling
net.ipv4.tcp_window_scaling = 1
##
net.ipv4.tcp_no_metrics_save = 1

Enquanto seletivo tcp ack é bom para o desempenho ideal no caso de rede de alta largura de banda. Mas cuidado com outras desvantagens . Os benefícios do escalonamento de janelas são descritos aqui . Quanto à terceira opção sysctl: Por padrão, o TCP salva várias métricas de conexão no cache da rota quando a conexão é fechada, para que as conexões estabelecidas em um futuro próximo possam usá-las para definir as condições iniciais. Geralmente, isso aumenta o desempenho geral, mas às vezes pode causar degradação do desempenho. Se definido, o TCP não armazenará em cache as métricas ao fechar as conexões.

Verifique com

ethtool -k ethX

para ver se o descarregamento está ativado ou não. Descarregamento de soma de verificação TCP e descarregamento de segmento grande são suportados pelo A maioria das NICs Ethernet de hoje e aparentemente Broadcom também a suporta .

Tente usar a ferramenta

powertop

enquanto a rede está inativa e quando a saturação da rede é atingida. Isso definitivamente irá mostrar se as interrupções NIC são o culpado. A pesquisa de dispositivos é uma resposta para tal situação. O FreeBsd suporta o polling dentro do ifconfig, mas o linux não tem essa opção. Consulte this para ativar o polling. Está dizendo que a BroadCom também oferece suporte a enquetes, o que é uma boa notícia para você.

O ajuste de pacotes jumbo pode não ser suficiente para você desde Você mencionou que seu tráfego é composto principalmente de pequenos pacotes. Mas hei experimentá-lo de qualquer maneira!

    
por 12.02.2012 / 06:22
1

você precisa distribuir a carga em todos os núcleos da CPU. Inicie o 'irqbalance'.

    
por 31.05.2013 / 03:54
1

Eu proponho isso:

kernel.sem = 350 358400 64 1024
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 4194304
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_adv_win_scale = 2
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_rmem = 4096 262144 4194304
net.ipv4.tcp_wmem = 4096 262144 4194304
net.ipv4.tcp_keepalive_time = 900
net.ipv4.tcp_keepalive_intvl = 900
net.ipv4.tcp_keepalive_probes = 9

Testado em servidores Oracle DB no RHEL e no software de backup.

    
por 19.02.2016 / 12:15
1

No meu caso, apenas um único tuninng:

net.ipv4.tcp_timestamps = 0

fez uma mudança muito grande e útil, o tempo de carregamento do site diminuiu em 50%.

    
por 19.02.2016 / 11:57
0

Eu notei na lista de ajustes que os timestamps estão desativados, por favor, não faça isso. Esse é um antigo retrocesso aos dias de outrora quando a largura de banda era muito cara e as pessoas queriam economizar alguns bytes / pacote. Ele é usado, por exemplo, pela pilha TCP atualmente para dizer se um pacote que chega a um soquete em "CLOSE_WAIT" é um pacote antigo para a conexão ou se é um novo pacote para uma nova conexão e ajuda nos cálculos RTT. E salvar os poucos bytes para um timestamp é NADA comparado com o que os endereços IPv6 irão adicionar. Desativar os timestamps causa mais mal do que bem.

Esta recomendação para desativar os timestamps é apenas um retrocesso que continua sendo passado de uma geração de sysadmin para a próxima. Tipo de coisa "lenda urbana".

    
por 13.05.2015 / 18:39