Skip to content

netpoll

Netpoll Go — это основной механизм мультиплексирования ввода-вывода, реализованный средой выполнения Go. Он позволяет Go реализовывать высокопроизводительные сетевые службы с лаконичной синхронной моделью программирования (одна Goroutine на соединение). По сути, это глубокая интеграция системных вызовов мультиплексирования ввода-вывода на уровне операционной системы (таких как epoll в Linux) с планировщиком Goroutine в Go.

Сравнение между Netpoll и собственной сетевой библиотекой Go

1. Количество Goroutines

  • Go Net: Одна Goroutine на соединение.
  • NetPoll: Несколько соединений под одной Goroutine.

2. Переключение контекста Goroutine/Давление планирования

  • Go Net: Высокое давление переключения при высокой конкурентности. Поскольку Go Net имеет одну Goroutine на соединение, происходит частое переключение при большом количестве goroutine.
  • NetPoll: Низкое давление переключения при высокой конкурентности. Поскольку NetPoll разделяет одну goroutine между несколькими соединениями, переключений меньше.

3. Потребление памяти

  • Go Net: Потребление памяти положительно коррелирует с количеством соединений. Высокая конкурентность может вызвать давление памяти из-за взрыва Goroutine.
  • NetPoll: Предварительно выделяет буферы и создаёт пул буферов.

4. Режим триггера

  • Go Net: Использует Edge Triggered (ET). Считывает все данные за раз, простая реализация.
  • NetPoll: Использует Level Triggered (LT). Не нужно предварительно выделять большую память как буферы данных.

5. Поддержка совместного использования пула буферов между ядром и пользовательским уровнем (на одну копию меньше)

  • Go Net: Не поддерживается.
  • NetPoll: Поддерживается. Управляет пулом буферов, который напрямую передаётся пользователям, требуя на одну копию меньше.

6. Применимые сценарии

  • Go Net: Низкая конкурентность, простые сценарии.
  • NetPoll: Высокая конкурентность, сценарии с низкой задержкой.

Концепции дизайна Netpoll

1. Базовая архитектура

Собственная сетевая библиотека разработана на основе режима epoll LT. Базовая архитектура показана на рисунке ниже:

базовая архитектура netpoll

2. Использование Goroutines

Существует пул объектов poll. Каждый объект poll имеет epoll и отдельно связан с goroutine. Количество goroutine согласовано с количеством объектов poll, и каждый объект poll может прослушивать несколько файловых дескрипторов (fd).

3. Логика чтения/записи I/O

  • Каждый объект poll запускает goroutine для непрерывного опроса читаемых/записываемых событий на текущем epoll.
  • Каждый epoll связан с несколькими fd, и каждый fd связан с Buffer.
  • Когда слышно читаемое событие от fd, данные читаются в Buffer.
  • Непрерывно опрашивает и обрабатывает данные в Buffer. Когда чтение данных завершено, уведомляет пул goroutine последующей логики обработки GoPoll для выполнения.
  • Взаимодействие с ядром через системные вызовы полностью контролируется netpoll. Чтения и записи пользовательского уровня в Conn просто оперируют общим Buffer.

4. Преимущества и недостатки

Преимущества: Более сильная поддержка возможностей высокой конкурентности.

  1. Опрос обрабатывает данные в Buffer, поэтому нет ситуации, когда данные не обрабатываются.
  2. Одна goroutine соответствует нескольким соединениям. Даже при большом количестве соединений накладные расходы планирования и переключения ресурсов не значительны.
  3. Поддерживает совместное использование буфера между пользователем и ядром, уменьшая одну операцию копирования данных и повышая эффективность.

Недостатки: Требуется больше памяти.

Golang by www.golangdev.cn edit