Mejora del rendimiento de TCP en una red de gigabits con muchas conexiones y mucho tráfico de paquetes pequeños

37

Estoy tratando de mejorar mi rendimiento TCP a través de una "red gigabit con muchas conexiones y mucho tráfico de paquetes pequeños". El sistema operativo de mi servidor es Ubuntu 11.10 Server 64bit.

Hay alrededor de 50,000 (y crecientes) clientes conectados a mi servidor a través de Sockets TCP (todos en el mismo puerto).

El 95% de mis paquetes tienen un tamaño de 1-150 bytes (encabezado TCP y carga útil). El 5% restante varía desde 150 hasta 4096+ bytes.

Con la configuración a continuación, mi servidor puede manejar el tráfico de hasta 30 Mbps (dúplex completo).

¿Pueden aconsejar las mejores prácticas para ajustar el sistema operativo a mis necesidades?

Mi /etc/sysctl.congaspecto es este:

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

Aquí están mis límites:

$ 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

[ADICIONAL]

Mis NIC son las siguientes:

$ 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

[AGREGADO 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

[AGREGADO 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

Alguna información sobre SACK: ¿ Cuándo desactivar TCP SACK?

Trabajador
fuente
¿Cuál es el factor limitante? ¿Tu CPU alcanza el máximo? Si es así, estás ladrando al árbol equivocado. Debes mirar lo que está haciendo la CPU.
David Schwartz
¿Qué NIC tienes?
SaveTheRbtz
1
Por cierto: ¿Por qué apagas SACK?
Nils
1
Debería reconsiderar el uso de NIC Broadcom ...
Hubert Kario

Respuestas:

21

El problema podría ser que está recibiendo demasiadas interrupciones en su tarjeta de red. Si el ancho de banda no es el problema, la frecuencia es el problema:

  • Suba las memorias intermedias de envío / recepción en la tarjeta de red

    ethtool -g eth0
    

Le mostrará la configuración actual (256 o 512 entradas). Probablemente pueda aumentarlos a 1024, 2048 o 3172. Más probablemente no tenga sentido. Esto es solo un buffer de anillo que solo se llena si el servidor no puede procesar los paquetes entrantes lo suficientemente rápido.

Si el búfer comienza a llenarse, el control de flujo es un medio adicional para indicarle al enrutador o al interruptor que disminuya la velocidad:

  • Active el control de flujo de entrada / salida en el servidor y los puertos del conmutador / enrutador al que está conectado.

    ethtool -a eth0
    

Probablemente mostrará:

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

Verifique / var / log / messages para la configuración actual de eth0. Comprueba si hay algo como:

eth0: Link está activo a 1000 Mbps, full duplex, control de flujo tx y rx

Si no ve tx y rx, los administradores de su red deben ajustar los valores en el conmutador / enrutador. En Cisco está activado el control de flujo de recepción / transmisión.

Tenga cuidado: cambiar estos valores hará que su enlace baje y suba por un tiempo muy corto (menos de 1s).

  • Si todo esto no ayuda, también puede reducir la velocidad de la tarjeta de red a 100 MBit (haga lo mismo en los puertos del conmutador / enrutador)

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

Pero en su caso, diría: aumente los búferes de recepción en el búfer de anillo NIC.

Nils
fuente
En cuanto a sus números ethtool, diría: configure las memorias intermedias de recepción de la tarjeta de red al máximo para evitar los descartes de RX. Espero que su Broadcom tenga suficiente de estos.
Nils
1
Aumentar el almacenamiento en búfer con TCP casi nunca es una buena idea. Hemos demasiado amortiguar ya: bufferbloat.net/projects/bloat/wiki/Introduction
rmalayter
3
Este búfer es un búfer de hardware directamente en la NIC. Actualizaré mi respuesta con más detalles. Como está perdiendo paquetes entrantes, necesita ese búfer. Tengo un servidor similar donde tuve que cambiar a una NIC diferente (de Broadcom a PCIe Intel a bordo) para poder aumentar estos búferes. Después de eso, nunca más encontré paquetes RX perdidos.
Nils
@malayter: este es un buffer de anillo en la capa 2. Vea mi respuesta actualizada.
Nils
1
Finalmente tenemos 1GB. Hubo muchos ajustes en diferentes lugares, por lo que realmente no puedo decir que haya un solo problema.
Trabajador
5

La siguiente puede no ser la respuesta definitiva, pero definitivamente presentará algunas ideas

Intente agregar estos a 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

Mientras que tcp ack selectivo es bueno para un rendimiento óptimo en el caso de una red de gran ancho de banda. Pero tenga cuidado con otros inconvenientes sin embargo. Los beneficios del escalado de ventanas se describen aquí . En cuanto a la tercera opción sysctl: de forma predeterminada, TCP guarda varias métricas de conexión en la caché de ruta cuando se cierra la conexión, de modo que las conexiones establecidas en un futuro próximo puedan usarlas para establecer las condiciones iniciales. Por lo general, esto aumenta el rendimiento general, pero a veces puede causar una degradación del rendimiento. Si se establece, TCP no almacenará en caché las métricas al cerrar las conexiones.

Verifícalo con

ethtool -k ethX

para ver si la descarga está habilitada o no. La descarga de suma de comprobación TCP y la descarga de segmento grande son compatibles con la mayoría de las NIC de Ethernet actuales y aparentemente Broadcom también lo admite.

Intenta usar la herramienta

powertop

mientras la red está inactiva y cuando se alcanza la saturación de la red. Esto definitivamente mostrará si las interrupciones de NIC son las culpables. El sondeo de dispositivos es una respuesta a tal situación. FreeBsd admite el interruptor de sondeo dentro de ifconfig, pero Linux no tiene esa opción. Consulte esto para habilitar el sondeo. Está diciendo que BroadCom también admite encuestas, que son buenas noticias para usted.

El ajuste de paquetes gigantes podría no ser suficiente para usted, ya que mencionó que su tráfico consiste principalmente en paquetes pequeños. ¡Pero oye, pruébalo de todos modos!

kaji
fuente
2kaji, intentaré tus sugerencias mañana. Acerca de PowerTop: ¿debo ajustar el ahorro de energía si mi objetivo es el rendimiento?
Trabajador
Sí, por supuesto, eso también podría ayudar. Mencioné Powertop solo para asegurarme de que las interrupciones sean malas. La frecuencia de las interrupciones también se puede obtener de otras herramientas
kaji
Veo altas "Interrupciones de reprogramación", ¿podría ser una razón? ¿Qué son las "interrupciones de reprogramación"?
Trabajador
Intenta seguir esto ---> help.ubuntu.com/community/ReschedulingInterrupts
kaji
sí ... vi ese tutorial, pero es para computadoras portátiles mientras veo altas interrupciones en el servidor. Intentará aplicarlo al servidor.
Trabajador
2

necesita distribuir la carga en todos los núcleos de CPU. Inicie 'irqbalance'.

usuario175978
fuente
1
Esto no ayudará si una sola IRQ tiene una frecuencia muy alta. IRQBalance intenta distribuir IRQ individuales a procesadores lógicos adecuados, pero nunca habrá más de un procesador que sirva a una única IRQ.
Nils
2

Noté en la lista de ajustes que las marcas de tiempo están desactivadas, por favor no hagas eso. Ese es un antiguo retroceso a los días de antaño, cuando el ancho de banda era realmente costoso y la gente quería ahorrar algunos bytes / paquete. Es utilizado, por ejemplo, por la pila TCP en estos días para saber si un paquete que llega para un socket en "CLOSE_WAIT" es un paquete antiguo para la conexión o si es un paquete nuevo para una nueva conexión y ayuda en los cálculos RTT. Y guardar los pocos bytes para una marca de tiempo NO ES NADA en comparación con lo que se agregarán las direcciones IPv6. Desactivar las marcas de tiempo hace más daño que bien.

Esta recomendación para desactivar las marcas de tiempo es solo un retroceso que sigue pasando de una generación de administrador de sistemas a la siguiente. Una especie de "leyenda urbana".

GeorgeB
fuente
2

Propongo esto:

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

Probado en servidores Oracle DB en RHEL y en software de respaldo.

Konrad Puchała
fuente
55
Estos números son configurables porque no hay una talla única para todos. Eso significa que los números en sí mismos no son valiosos. Lo que podría ser valioso es el método que usó para decidir qué números usar.
kasperd
2

En mi caso, solo un solo ajuste:

net.ipv4.tcp_timestamps = 0

hizo un cambio muy grande y útil, el tiempo de carga del sitio disminuyó en un 50%.

avz2012
fuente
Algo debe estar severamente roto en su configuración para que eso suceda. Las marcas de tiempo usan menos del 1% del ancho de banda en circunstancias normales y permitirán que TCP realice retransmisiones mucho más estrictamente cronometradas que de lo contrario.
kasperd