Fragmentación de sockets en NGINX 1.9.1

NGINX | 26 de mayo de 2015

NGINX 1.9.1 incorpora una nueva función que permite utilizar la opción de socket SO_REUSEPORT, disponible en las versiones más recientes de muchos sistemas operativos, incluidos DragonFly BSD y Linux (versión 3.9 del kernel y posteriores). Esta opción permite que varios sockets escuchen en la misma combinación de dirección IP y puerto. A continuación, el kernel distribuye la carga de las conexiones entrantes entre los sockets.

Nota del editor: Para los usuarios de NGINX Plus, esta función es compatible con NGINX Plus versión 7 (R7) y posteriores. Para obtener una visión general de todas las novedades de esa versión, consulte Anuncio de NGINX Plus R7 en nuestro blog.

La opción de socket SO_REUSEPORT tiene muchas aplicaciones prácticas potenciales. Otros servicios pueden utilizarla para realizar fácilmente actualizaciones graduales de los ejecutables (NGINX ya admite las actualizaciones graduales mediante otros métodos). En NGINX, habilitar esta opción de socket puede mejorar el rendimiento en determinados escenarios al reducir la contención de bloqueos.

Como se muestra en la figura, cuando la opción SO_REUSEPORT no está habilitada, un único socket de escucha notifica a los procesos de trabajo de las conexiones entrantes, y cada uno de ellos intenta aceptar una conexión.

Con la opción SO_REUSEPORT habilitada, hay varios sockets de escucha para cada combinación de dirección IP y puerto, uno por cada proceso de trabajo. El kernel determina qué socket de escucha disponible (y, por tanto, qué proceso de trabajo) recibe la conexión. Esto puede reducir la contención de bloqueos entre los procesos de trabajo que aceptan nuevas conexiones y mejorar el rendimiento en sistemas multinúcleo. Sin embargo, también puede implicar que, cuando un proceso de trabajo queda detenido por una operación bloqueante, el bloqueo no solo afecte a las conexiones que ya ha aceptado, sino también a las solicitudes de conexión que el kernel le haya asignado desde que quedó bloqueado.

Configuración de la fragmentación de sockets

Para habilitar la opción de socket SO_REUSEPORT, incluya el nuevo parámetro reuseport en la directiva listen para el tráfico HTTP o TCP (módulo stream), como en estos ejemplos:

http {     server {
          listen 80 reuseport;
          server_name  localhost;
          # ...
     }
}

stream {
     server {
          listen 12345 reuseport;
          # ...
     }
}

Incluir el parámetro reuseport también deshabilita la directiva accept_mutex para el socket, ya que el mutex resulta redundante con reuseport. Aun así, puede ser conveniente configurar accept_mutex si hay puertos en los que no se configura reuseport.

Evaluación comparativa del rendimiento con reuseport

Ejecuté una prueba de rendimiento con wrk utilizando 4 procesos de trabajo de NGINX en una instancia de AWS de 36 núcleos. Para eliminar los efectos de la red, ejecuté tanto el cliente como NGINX en localhost e hice que NGINX devolviera la cadena OK en lugar de un archivo. Comparé tres configuraciones de NGINX: la predeterminada (equivalente a accept_mutex on), con accept_mutex off y con reuseport. Como se muestra en la figura, reuseport multiplica por entre 2 y 3 el número de solicitudes por segundo y reduce tanto la latencia como su desviación estándar.

prueba de rendimiento de reuseport

También ejecuté una prueba de rendimiento relacionada con el cliente y NGINX en hosts distintos, y con NGINX devolviendo un archivo HTML. Como se muestra en la tabla siguiente, con reuseport la reducción de la latencia fue similar a la de la prueba anterior, y la desviación estándar disminuyó de forma aún más drástica (casi diez veces). Otros resultados (no mostrados en la tabla) también fueron alentadores. Con reuseport, la carga se distribuyó uniformemente entre los procesos de trabajo. En la configuración predeterminada (equivalente a accept_mutex on), algunos procesos recibieron un porcentaje mayor de la carga, mientras que con accept_mutex off todos los procesos experimentaron una carga elevada.

Latencia (ms) Desviación estándar de la latencia (ms) Carga de CPUPredeterminado 15.65 26.59 0.3accept_mutex off 15.59 26.48 10reuseport 12.35 3.15 0.3

En estas pruebas de rendimiento, la tasa de solicitudes de conexión es alta, pero las solicitudes no requieren un procesamiento exhaustivo. Otras pruebas preliminares también indican que reuseport mejora más el rendimiento cuando el tráfico se ajusta a este perfil. (El parámetro reuseport no está disponible en la directiva listen en el contexto mail, por ejemplo, porque el tráfico de correo electrónico claramente no se ajusta a este perfil). Le recomendamos que pruebe reuseport para determinar si mejora el rendimiento de su implementación de NGINX, en lugar de aplicarlo de forma generalizada. Para obtener algunos consejos sobre cómo probar el rendimiento de NGINX, consulte la charla de Konstantin Pavlov en nginx.conf 2014.

Agradecimientos

Gracias a Yingqi Lu, de Intel, y a Sepherosa Ziehau, quienes aportaron sendas soluciones al proyecto NGINX que permiten utilizar la opción de socket «SO_REUSEPORT». El equipo de NGINX combinó ideas de ambas contribuciones para crear lo que consideramos una solución ideal.


Compartir

Artículos relacionados del blog

Únete a F5 NGINX en AppWorld 2024
NGINX | 04/01/2024

Únete a F5 NGINX en AppWorld 2024

Descubre las numerosas razones para asistir al evento insignia de F5, que incluirá un emocionante anuncio sobre la cartera de productos NGINX.

Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source
NGINX | 26/09/2023

Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source

La función de diccionario compartido permite configurar NGINX sin necesidad de reiniciarlo al renovar los certificados SSL/TLS.

Exposición de APIs en Kubernetes
NGINX | 10/03/2022

Exposición de APIs en Kubernetes

La unidad 2 de Microservices March 2022 se centra en cómo exponer tus API en Kubernetes. Aquí tienes enlaces a los recursos que necesitas: la retransmisión en directo del 14 de marzo, artículos de blog y otros recursos de preparación, y el laboratorio práctico «Protege las API de Kubernetes mediante la limitación de solicitudes».

NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto
NGINX | 23/08/2021

NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto

Hoy, en NGINX Sprint 2.0, anunciamos cómo respaldaremos nuestra visión del futuro de las aplicaciones modernas con una mayor presencia en la comunidad de código abierto, incluida la participación en el proyecto comunitario Kubernetes, nuevos proyectos de software de código abierto y la arquitectura de referencia para aplicaciones modernas.

Presentamos NGINX Plus R22
NGINX | 09/06/2020

Presentamos NGINX Plus R22

NGINX Plus R22 incorpora nuevas funcionalidades, como la compatibilidad con OCSP para verificar la revocación de certificados en TLS mutuo, el uso de varios proveedores de identidad OIDC en una configuración, el seguimiento en tiempo real de la limitación de solicitudes y conexiones en el panel de NGINX Plus y mejoras en NGINX JavaScript.

Presentamos NGINX Plus R17
NGINX | 11/12/2018

Presentamos NGINX Plus R17

NGINX Plus R17 incorpora compatibilidad con la limitación de velocidad en dos fases y con TLS 1.3, la versión más reciente del protocolo Transport Layer Security. La configuración de OpenID Connect es más sencilla y NGINX ModSecurity WAF es el doble de rápido que antes. También se ha actualizado el módulo JavaScript de NGINX.