Netpoll
O netpoll do Go é o mecanismo central de multiplexação de I/O implementado pelo runtime da linguagem Go. Ele permite que o Go implemente serviços de rede de alto desempenho com um modelo de programação síncrono conciso (uma Goroutine por conexão). Sua essência é combinar profundamente as chamadas de sistema de multiplexação de I/O do sistema operacional subjacente (como epoll do Linux) com o escalonador de Goroutines do Go.
Comparação entre Netpoll e GoNet Nativo
1. Número de Goroutines
- Go Net: Uma Goroutine tem apenas uma conexão.
- NetPoll: Uma Goroutine tem múltiplas conexões.
2. Pressão de Troca de Contexto e Escalonamento de Goroutines
- Go Net: Alta pressão de troca em alta concorrência. Como GoNet tem uma conexão correspondendo a uma goroutine, quando o número de goroutines é alto, as trocas são frequentes.
- NetPoll: Baixa pressão de troca em alta concorrência. Como NetPoll tem múltiplas conexões compartilhando uma goroutine, o número de trocas é menor.
3. Consumo de Memória
- Go Net: O consumo de memória é positivamente correlacionado com o número de conexões. Em alta concorrência, pode causar pressão de memória devido à explosão do número de Goroutines.
- NetPoll: Pré-aloca buffers e cria um pool de buffers.
4. Método de Acionamento
- Go Net: Usa acionamento de borda (ET). Lê todos os dados de uma vez, implementação simples.
- NetPoll: Usa acionamento de nível (LT). Não precisa pré-alocar memória suficientemente grande como buffer de dados.
5. Suporte para Compartilhamento de Pool de Buffers entre Kernel e Camada de Usuário, Reduzindo uma Cópia de Dados
- Go Net: Não suporta.
- NetPoll: Suporta. Gerencia um pool de Buffer diretamente entregue ao usuário, reduzindo uma cópia de dados.
6. Cenários de Aplicação
- Go Net: Cenários simples de baixa concorrência.
- NetPoll: Cenários de alta concorrência e baixa latência.
Ideia de Design do Netpoll
1. Arquitetura Básica
A biblioteca de rede nativa é desenvolvida baseada no modo lt do epoll. A arquitetura básica é mostrada na figura abaixo:

2. Uso de Goroutines
Existe um pool de objetos poll, onde cada objeto poll tem um epoll e corresponde separadamente a uma goroutine. O número de goroutines é consistente com o número de objetos poll. Cada objeto poll pode monitorar múltiplos descritores de arquivo fd.
3. Lógica de Leitura/Escrita de I/O
- Cada objeto poll inicia uma goroutine para continuamente sondar eventos legíveis/escrevíveis no epoll atual.
- Cada epoll associa múltiplos fd, e cada fd associa um Buffer.
- Quando um evento legível é detectado no fd, os dados são lidos no Buffer.
- Continua sondando e processando os dados no Buffer. Quando descobre que os dados foram lidos completamente, notifica o pool de goroutines GoPoll da lógica de processamento posterior para executar.
- A interação com chamadas de sistema do kernel é completamente controlada pelo netpoll. Leitura e escrita do usuário em Conn são apenas operações no Buffer compartilhado.
4. Vantagens e Desvantagens
Vantagens: Suporta capacidade de alta concorrência mais forte.
- Sondagem contínua processa dados do Buffer, não existe situação de dados não serem processados.
- Uma goroutine corresponde a múltiplas conexões. Mesmo que haja muitas conexões, a sobrecarga de troca de escalonamento de recursos não é significativa.
- Suporta compartilhamento de buffer entre usuário e kernel, reduzindo uma operação de cópia de dados, melhorando a eficiência.
Desvantagens: Requer ocupação de mais memória.
