Notas de estudio práctico sobre optimización del rendimiento de Linux NET

El siguiente contenido es del curso de geek; si le resulta útil, consulte el póster del curso detallado:
Nombre de la imagen

Rendimiento NETO

Conocimientos relacionados con el rendimiento de .NET

1. Conocimientos básicos

A continuación, la pila de protocolos del kernel saca la trama de red del búfer y procesa la trama de red capa por capa de abajo hacia arriba a través de la pila de protocolos de red. tal como,

  1. Verifique la legitimidad del mensaje en la capa de enlace para averiguar el tipo de protocolo de la capa superior (como IPv4 o IPv6), luego elimine el encabezado y la cola de la trama, y ​​luego entréguelo a la capa de red.
  2. La capa de red saca el encabezado IP y juzga la siguiente dirección del paquete de red, como si se entrega a la capa superior para su procesamiento o reenvío. Cuando la capa de red confirma que el paquete se enviará a la máquina local, eliminará el tipo de protocolo de capa superior (como TCP o UDP), eliminará el encabezado IP y lo entregará a la capa de transporte para su procesamiento. .
  3. Después de que la capa de transporte saca el encabezado TCP o el encabezado UDP, encuentra el Socket correspondiente de acuerdo con la <IP de origen, puerto de origen, IP de destino, puerto de destino> cuadruplica como identificador y copia los datos en el búfer de recepción del Socket. .
  4. Finalmente, la aplicación puede usar la interfaz de Socket para leer los datos recién recibidos.

2. Indicadores NIC

Cuarto, el número de bytes, paquetes, errores y condiciones de pérdida de paquetes enviados y recibidos por la red, especialmente cuando los errores, caídas, desbordamientos, portadores y colisiones de las partes TX y RX no son 0, generalmente significa que el pregunta de E / S de red. entre ellos:

  • errores representa el número de paquetes con errores, como errores de verificación, errores de sincronización de tramas, etc .;
  • descartado indica el número de paquetes descartados, es decir, el paquete ha recibido el búfer de anillo, pero el paquete se descarta debido a memoria insuficiente y otras razones;
  • Overruns significa el número de paquetes de datos overrun, es decir, la velocidad de E / S de la red es demasiado rápida, lo que hace que los paquetes de datos en el Ring Buffer lleguen demasiado tarde para procesarse (la cola está llena) y se produce la pérdida de paquetes;
  • portadora indica la cantidad de paquetes con errores de portadora, como desajuste en el modo dúplex, problemas con los cables físicos, etc .;
  • collisions representa el número de paquetes de colisión.

3. Optimización de problemas de C10K, C1000K

Optimización del modelo IO
  • Activador horizontal: siempre que el descriptor de archivo pueda realizar un bloqueo de E / S, se activará una notificación. En otras palabras, la aplicación puede verificar el estado del descriptor de archivo en cualquier momento y luego realizar operaciones de E / S según el estado.
  • Disparador de borde: solo cuando cambia el estado del descriptor de archivo (es decir, se alcanza la solicitud de E / S), se envía una notificación. En este momento, la aplicación debe realizar la mayor cantidad de E / S posible y puede detenerse hasta que ya no pueda continuar leyendo o escribiendo. Si no se completa la E / S, o por alguna razón no hay tiempo para procesar, la notificación se perderá.
  1. La primera es utilizar E / S sin bloqueo y notificaciones de activación de nivel, como seleccionar o sondear.
  2. El segundo es utilizar E / S sin bloqueo y notificaciones de activación de borde, como epoll.
  3. El tercero es utilizar E / S asíncronas (E / S asíncronas, denominadas AIO)
Optimización del modelo de trabajo

1. El primer tipo, el proceso principal + múltiples procesos secundarios trabajadores, también es el modelo más utilizado.
Cabe señalar aquí que las llamadas accept () y epoll_wait (), todavía hay un problema impactante. En otras palabras, cuando ocurre un evento de E / S de red, varios procesos se despiertan al mismo tiempo, pero de hecho solo un proceso responde a este evento y otros procesos activados volverán a dormir. Entre ellos, el problema del grupo de choque de accept () ha sido resuelto en Linux 2.6; y el problema de epoll, fue solo en Linux 4.5 que fue resuelto por EPOLLEXCLUSIVE. Para evitar el problema del grupo de choque, Nginx agrega un bloqueo global (accept_mutex) a cada proceso de trabajo. Estos procesos de trabajo deben competir por el bloqueo primero, y solo los procesos que compiten por el bloqueo se agregarán a epoll, para garantizar que solo se despierte un proceso hijo de trabajador.
2. El segundo, un modelo multiproceso que escucha el mismo puerto

4. Cómo evaluar el rendimiento de la red del sistema

  • En la capa de la aplicación, puede usar wrk, Jmeter, etc. para simular la carga de usuarios, probar el número de solicitudes por segundo, el retraso de procesamiento, el número de errores, etc. de la aplicación;
  • En la capa de transporte, puede utilizar herramientas como iperf para probar el rendimiento de TCP;
  • Más abajo, también puede usar el pktgen que viene con el kernel de Linux para probar el PPS del servidor.

5. Cómo optimizar DDos

  1. Limite el número de conexiones simultáneas y la frecuencia de SYN según la IP de origen
# 限制syn并发数为每秒1次
$ iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT
# 限制单个IP在60秒新建立的连接数为10
$ iptables -I INPUT -p tcp --dport 80 --syn -m recent --name SYN_FLOOD --update --seconds 60 --hitcount 10 -j REJECT
  1. Aumente el número de conexiones semiabiertas, el valor predeterminado es 256
$ $ sysctl -w net.ipv4.tcp_max_syn_backlog=1024
net.ipv4.tcp_max_syn_backlog = 1024
  1. Al conectar cada SYN_RECV, si falla, el kernel lo reintentará automáticamente y el número predeterminado de reintentos es 5. Puede ejecutar el siguiente comando para reducirlo a 1 vez:
    $ sysctl -w net.ipv4.tcp_synack_retries = 1
  2. Activar SYN Cookies
$ sysctl -w net.ipv4.tcp_syncookies=1
net.ipv4.tcp_syncookies = 1

6. El cliente TCP_QUICKACK está apagado + el servidor está encendido Nagle, lo que hace que el retraso aumente

Inserte la descripción de la imagen aquí

7. Cómo optimizar NAT

Ajuste principalmente los parámetros predeterminados de la tabla de seguimiento de conexiones. Indicadores importantes:

  • net.netfilter.nf_conntrack_count, que significa el número de seguimiento de la conexión actual;
  • net.netfilter.nf_conntrack_max, que indica el número máximo de seguimiento de conexiones;
  • net.netfilter.nf_conntrack_buckets indica el tamaño de la tabla de seguimiento de conexiones.

Tamaño de memoria ocupado por la tabla de seguimiento de conexiones:

# 连接跟踪对象大小为376,链表项大小为16
nf_conntrack_max*连接跟踪对象大小+nf_conntrack_buckets*链表项大小 
= 1000*376+65536*16 B
= 1.4 MB

Materiales de referencia:
https://mp.weixin.qq.com/s/VYBs8iqf0HsNg9WAxktzYQ

8. Ideas comunes para la optimización del rendimiento de la red

solicitud

  • Utilice epoll + aio, etc .;
  • El uso de conexiones largas en lugar de conexiones cortas puede reducir significativamente el costo del establecimiento de la conexión TCP. Cuando el número de solicitudes por segundo es alto, el efecto de esto es muy obvio.
  • El uso de memoria y otros métodos para almacenar en caché los datos que no cambian con frecuencia puede reducir el número de E / S de red y acelerar la velocidad de respuesta de la aplicación.
  • El uso de métodos de serialización como el búfer de protocolo para comprimir el volumen de datos de la E / S de la red puede mejorar el rendimiento de la aplicación.
  • Utilice el almacenamiento en caché de DNS, la búsqueda previa, HTTPDNS y otros métodos para reducir el retraso de la resolución de DNS y mejorar la velocidad general de E / S de la red.

Enchufe

Por lo tanto, para mejorar el rendimiento de la red, normalmente es necesario ajustar el tamaño de estos búferes. tal como:

  • Aumente el tamaño del búfer de cada socket net.core.optmem_max;
  • Aumente el tamaño del búfer de recepción del zócalo net.core.rmem_max y el tamaño del búfer de envío net.core.wmem_max;
  • Aumente el tamaño del búfer de recepción de TCP net.ipv4.tcp_rmem y el tamaño del búfer de envío net.ipv4.tcp_wmem.

Inserte la descripción de la imagen aquí
Por ejemplo, el tamaño del búfer de envío, el valor ideal es rendimiento * retardo, de modo que se pueda lograr la máxima utilización de la red.
Además, la interfaz de socket también proporciona algunas opciones de configuración para modificar el comportamiento de la conexión de red:

  • Después de configurar TCP_NODELAY para la conexión TCP, el algoritmo de Nagle se puede desactivar;
  • Después de abrir TCP_CORK para la conexión TCP, los paquetes pequeños se pueden agregar en paquetes grandes antes de enviarlos (tenga en cuenta que bloqueará el envío de paquetes pequeños);
  • Con SO_SNDBUF y SO_RCVBUF, puede ajustar el tamaño del búfer de envío y recepción del socket, respectivamente.

Capa de transporte

En la primera categoría, en un escenario en el que la cantidad de solicitudes es relativamente grande, es posible que vea una gran cantidad de conexiones en el estado TIME_WAIT, lo que ocupará mucha memoria y recursos de puerto. En este momento, podemos optimizar las opciones del kernel relacionadas con el estado TIME_WAIT, como tomar las siguientes medidas.

  • Aumente el número de conexiones net.ipv4.tcp_max_tw_buckets en el estado TIME_WAIT y aumente el tamaño de la tabla de seguimiento de conexiones net.netfilter.nf_conntrack_max.
  • Reduzca net.ipv4.tcp_fin_timeout y net.netfilter.nf_conntrack_tcp_timeout_time_wait para permitir que el sistema libere los recursos que ocupan lo antes posible.
  • Habilite la reutilización de puertos net.ipv4.tcp_tw_reuse. De esta forma, el puerto ocupado por el estado TIME_WAIT también se puede utilizar en la conexión recién creada.
  • Aumente el rango de puertos locales net.ipv4.ip_local_port_range. De esta manera, se pueden admitir más conexiones y se puede mejorar la concurrencia general.
  • Aumente el número máximo de descriptores de archivos. Puede usar fs.nr_open y fs.file-max para aumentar el número máximo de descriptores de archivo para el proceso y el sistema respectivamente; o configurar LimitNOFILE en el archivo de configuración systemd de la aplicación para establecer el número máximo de descriptores de archivo para la aplicación.

La segunda categoría, para paliar los problemas de rendimiento causados ​​por ataques que utilizan características del protocolo TCP, como SYN FLOOD, puede considerar optimizar las opciones del kernel relacionadas con el estado SYN, como tomar las siguientes medidas.

La tercera categoría, en el escenario de conexión larga, generalmente se utiliza keepalive para detectar el estado de la conexión TCP, de modo que después de desconectar la conexión entre pares, se pueda reciclar automáticamente. Sin embargo, el intervalo de detección de Keepalive predeterminado del sistema y el número de reintentos generalmente no pueden cumplir con los requisitos de rendimiento de la aplicación. Por lo tanto, necesita optimizar las opciones del kernel relacionadas con Keepalive en este momento, como por ejemplo:

  • Acorte el intervalo entre el último paquete de datos y el paquete de detección Keepalive net.ipv4.tcp_keepalive_time;
  • Acorte el intervalo de tiempo para enviar paquetes de detección Keepalive net.ipv4.tcp_keepalive_intvl;
  • Reduzca el número de reintentos net.ipv4.tcp_keepalive_probes después de que falle la sonda Keepalive hasta que se notifique a la aplicación.

Inserte la descripción de la imagen aquí
UDP proporciona un protocolo de red orientado a datagramas, no requiere una conexión de red y no ofrece garantías de fiabilidad. Por lo tanto, la optimización UDP es mucho más simple que TCP. Aquí también resumí varios esquemas de optimización comunes.

  • Como se mencionó en la parte anterior del socket, aumente el tamaño del búfer del socket y el rango del búfer UDP;
  • Como se mencionó en la sección anterior de TCP, aumente el rango de números de puerto local;
  • Según el tamaño de MTU, ajuste el tamaño del paquete de datos UDP para reducir o evitar la fragmentación.

Capa de enlace

Debido a que el controlador de interrupciones (especialmente la interrupción suave) llama después de que la tarjeta de red recibe el paquete, necesita consumir una gran cantidad de CPU. Por lo tanto, programar estos manejadores de interrupciones para que se ejecuten en diferentes CPU puede mejorar significativamente el rendimiento de la red. Por lo general, esto se puede hacer de las dos formas siguientes. tal como,

  • Puede configurar la afinidad de la CPU (smp_affinity) para la interrupción brusca de la tarjeta de red o habilitar el servicio irqbalance.
  • Por otro ejemplo, puede habilitar RPS (Dirección de recepción de paquetes) y RFS (Dirección de flujo de recepción) para programar aplicaciones y procesamiento de interrupciones suaves en la misma CPU, de modo que pueda aumentar la tasa de aciertos de la caché de la CPU y reducir la latencia de la red.

Además, las tarjetas de red actuales tienen funciones muy ricas.Las funciones que originalmente fueron procesadas por software en el kernel pueden descargarse a la tarjeta de red y ejecutarse por hardware.

  • TSO (TCP Segmentation Offload) y UFO (UDP Fragmentation Offload): envía paquetes grandes directamente en el protocolo TCP / UDP; y funciones de segmentación de paquetes TCP (de acuerdo con la segmentación de MSS) y UDP (de acuerdo con la segmentación de MTU), completado por la tarjeta de red.
  • GSO (Descarga de segmentación genérica): cuando la tarjeta de red no admite TSO / UFO, la segmentación de los paquetes TCP / UDP se retrasará hasta que ingrese a la tarjeta de red antes de la ejecución. De esta manera, no solo se puede reducir el consumo de la CPU, sino que también solo se pueden retransmitir los paquetes fragmentados cuando se produce la pérdida de paquetes.
  • LRO (descarga de recepción grande): al recibir paquetes TCP segmentados, la tarjeta de red los ensambla y fusiona, y luego los envía a la red superior para su procesamiento. Sin embargo, debe tenerse en cuenta que cuando se requiere el reenvío de IP, LRO no se puede activar, porque si la información del encabezado de varios paquetes es inconsistente, la combinación de LRO provocará errores de verificación de paquetes de red.
  • GRO (Descarga de recepción genérica): GRO corrige las fallas de LRO y es más versátil, soporta tanto TCP como UDP.
  • RSS (Escalado lateral de recepción): también conocido como recepción de múltiples colas, asigna procesos de recepción de red en función de múltiples colas de recepción en el hardware, de modo que varias CPU pueden procesar los paquetes de red recibidos.
  • Desinstalación de VXLAN: es decir, deje que la tarjeta de red complete la función del paquete VXLAN.

?? Con respecto a tcp, hay un parámetro de verificación sobre las marcas de tiempo de apertura: tcp_timestamps. No lo abra si hay un entorno nat. Puede verificar si desea abrir cat / proc / sys / net / ipv4 / tcp_timestamps

Comandos comunes en la red

1. Información de socket ss o netstat

# head -n 3 表示只显示前面3行
# -l 表示只显示监听套接字
# -n 表示显示数字地址和端口(而不是名字)
# -p 表示显示进程信息
$ netstat -nlp | head -n 3
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 840/systemd-resolve

# -l 表示只显示监听套接字
# -t 表示只显示 TCP 套接字
# -n 表示显示数字地址和端口(而不是名字)
# -p 表示显示进程信息
$ ss -ltnp | head -n 3
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=840,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1459,fd=3))

Entre ellos, la cola de recepción (Recv-Q) y la cola de envío (Send-Q) necesitan su atención especial, y normalmente deberían ser 0. Cuando encuentra que no son 0, significa que hay acumulación de paquetes de red. Por supuesto, también tenga en cuenta que en diferentes estados de socket, sus significados son diferentes.
Cuando el enchufe está en un estado conectado (establecido),

  • Recv-Q representa el número de bytes en el búfer de socket que la aplicación no ha quitado (es decir, la longitud de la cola de recepción).
  • Y Send-Q representa la cantidad de bytes que no han sido confirmados por el host remoto (es decir, la longitud de la cola de envío).

Cuando el enchufe está en estado de escucha (escuchando),

  • Recv-Q representa la longitud de la cola completamente conectada.
  • Y Send-Q representa la longitud máxima de la cola completamente conectada.

La llamada conexión completa significa que el servidor recibe el ACK del cliente, completa el protocolo de enlace de tres vías de TCP y luego mueve la conexión a la cola de conexión completa. Los sockets en estas conexiones completas deben ser eliminados por la llamada al sistema accept () antes de que el servidor pueda procesar la solicitud del cliente. En correspondencia con la cola completamente conectada, también hay una cola semiconectada. La llamada media conexión se refiere a una conexión que no ha completado el protocolo de enlace de tres vías de TCP y la conexión solo está a mitad de camino. Una vez que el servidor recibe el paquete SYN del cliente, colocará la conexión en la cola de semiconexión y luego enviará el paquete SYN + ACK al cliente.

2. Información de la pila de protocolos ss -s o netstat -s

3. Rendimiento de la red y PPS (sar)

# 数字1表示每隔1秒输出一组数据
$ sar -n DEV 1
Linux 4.15.0-1035-azure (ubuntu) 01/06/19 _x86_64_ (2 CPU)
13:21:40 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
13:21:41 eth0 18.00 20.00 5.79 4.25 0.00 0.00 0.00 0.00
13:21:41 docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
13:21:41 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

Hay muchos indicadores de salida aquí, permítanme explicar brevemente su significado.

  • rxpck / sy txpck / s son los PPS recibidos y enviados, y la unidad es paquete / segundo.
  • rxkB / sy txkB / s son el rendimiento de recepción y envío, respectivamente, y la unidad es KB / seg.
  • rxcmp / sy txcmp / s son el número de paquetes de datos comprimidos recibidos y enviados, y la unidad es paquete / segundo.
  • % ifutil es la tasa de uso de la interfaz de red, a saber (rxkB / s + txkB / s) / Ancho de banda en modo semidúplex y máx (rxkB / s, txkB / s) / Ancho de banda en modo dúplex completo.

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/zimu312500/article/details/114239806
Recomendado
Clasificación