Skip to content

Netpoll

Netpoll de Go es el mecanismo central de multiplexación de I/O implementado por el tiempo de ejecución (runtime) del lenguaje Go. Permite que Go implemente servicios de red de alto rendimiento con un modelo de programación síncrono simple (un Goroutine por conexión). Su esencia es combinar profundamente las llamadas al sistema de multiplexación de I/O del sistema operativo subyacente (como epoll de Linux) con el planificador de Goroutines de Go.

Comparación entre Netpoll y GoNet Nativo

1. Número de Goroutines

Go Net: Un Goroutine tiene solo una conexión.

NetPoll: Un Goroutine tiene múltiples conexiones.

2. Presión de Cambio de Contexto y Programación de Goroutines

Go Net: Alta presión de cambio en concurrencia alta. Debido a que GoNet tiene una conexión por Goroutine, cuando hay muchas conexiones, los cambios son frecuentes.

NetPoll: Baja presión de cambio en concurrencia alta. Debido a que NetPoll tiene múltiples conexiones compartiendo un Goroutine, el número de cambios es menor.

3. Consumo de Memoria

Go Net: El consumo de memoria está positivamente correlacionado con el número de conexiones. En alta concurrencia, puede causar presión de memoria debido a la explosión en el número de Goroutines.

NetPoll: Se asignan búferes previamente y se crea un pool de búferes.

4. Método de Activación

Go Net: Usa activación de borde (ET - Edge Triggered). Lee todos los datos de una vez, implementación simple.

NetPoll: Usa activación de nivel (LT - Level Triggered). No es necesario asignar previamente memoria suficientemente grande como búfer de datos.

5. Soporte para Pool de Búferes Compartido entre Kernel y Capa de Usuario

Go Net: No soportado.

NetPoll: Soportado. Se gestiona un pool de Buffer que se entrega directamente al usuario, reduciendo una copia de datos.

6. Escenarios de Aplicación

Go Net: Escenarios simples de baja concurrencia.

NetPoll: Escenarios de alta concurrencia y baja latencia.

Diseño de Netpoll

1. Arquitectura Básica

La biblioteca de red nativa se basa en el modo LT de epoll. La arquitectura básica se muestra en la siguiente figura:

Arquitectura básica de netpoll

2. Uso de Goroutines

Existe un pool de objetos poll, cada objeto poll tiene un epoll y corresponde a un Goroutine individual. El número de Goroutines es consistente con el número de objetos poll, y cada objeto poll puede escuchar múltiples descriptores de archivo (fd).

3. Lógica de Lectura/Escritura de I/O

  • Cada objeto poll inicia un Goroutine para sondear continuamente eventos legibles/escribibles en el epoll actual.
  • Cada epoll está asociado con múltiples fd, y cada fd está asociado con un Buffer.
  • Cuando se detecta un evento legible en el fd, los datos se leen en el Buffer.
  • Se sondea continuamente el procesamiento de datos en el Buffer. Cuando se detecta que los datos están completamente leídos, se notifica al pool de Goroutines de procesamiento posterior GoPoll para ejecutar.
  • La interacción con las llamadas al sistema del kernel está completamente controlada por netpoll. Las operaciones de lectura/escritura del usuario en Conn solo operan el Buffer compartido.

4. Ventajas y Desventajas

Ventajas: Capacidad de alta concurrencia más fuerte.

  1. El procesamiento por sondeo de datos en el Buffer evita que los datos no sean procesados.
  2. Un Goroutine corresponde a múltiples conexiones. Incluso si hay muchas conexiones, el gasto de cambio y programación de recursos no es significativo.
  3. Soporta búfer compartido entre usuario y kernel, reduciendo una operación de copia de datos y mejorando la eficiencia.

Desventajas: Requiere más memoria.

Golang editado por www.golangdev.cn