netpoll
Go's netpoll ist der zentrale I/O-Multiplexing-Mechanismus der Go-Laufzeitumgebung (runtime). Er ermöglicht es Go, Hochleistungs-Netzwerkdienste mit einem einfachen synchronen Programmiermodell (eine Goroutine pro Verbindung) zu implementieren. Im Wesentlichen verbindet er die I/O-Multiplexing-Systemaufrufe des Betriebssystems (wie Linux epoll) tief mit dem Go-Goroutine-Scheduler.
Netpoll vs. natives GoNet
- Anzahl der Goroutinen Go Net: Eine Goroutine verwaltet nur eine Verbindung.
NetPoll: Eine Goroutine verwaltet mehrere Verbindungen.
- Belastung durch Goroutine-Kontextwechsel Go Net: Hohe Belastung bei hoher Parallelität. Da GoNet eine Verbindung einer Goroutine zuordnet, finden bei vielen Goroutinen häufige Wechsel statt.
NetPoll: Geringe Belastung bei hoher Parallelität. Da NetPoll mehrere Verbindungen auf einer Goroutine gemeinsam nutzt, gibt es weniger Wechsel.
- Speicherverbrauch: Go Net: Der Speicherverbrauch korreliert mit der Anzahl der Verbindungen. Bei hoher Parallelität kann es durch die Explosion der Goroutine-Anzahl zu Speicherdruck kommen.
NetPoll: Vorab zugewiesene Puffer, Erstellung von Puffer-Pools.
- Auslösemodus Go Net: Verwendet Edge Triggered (ET). Daten werden auf einmal gelesen, einfache Implementierung.
NetPoll: Verwendet Level Triggered (LT). Keine Notwendigkeit, vorab ausreichend große Speicherpuffer zuzuweisen.
- Unterstützung für gemeinsame Buffer-Pools zwischen Kernel und Userspace (eine Datenkopie weniger) Go Net: Nicht unterstützt.
NetPoll: Unterstützt. Verwaltet einen Buffer-Pool, der direkt an den Benutzer übergeben wird, was eine Datenkopie spart.
- Anwendungsbereiche Go Net: Einfache Szenarien mit geringer Parallelität
NetPoll: Szenarien mit hoher Parallelität und geringer Latenz
Netpoll Designkonzept
Grundarchitektur Die native Netzwerkbibliothek wurde auf Basis des epoll LT-Modus entwickelt. Die Grundarchitektur ist in der folgenden Abbildung dargestellt:

Verwendung von Goroutinen Es existiert ein Pool von Poll-Objekten. Jedes Poll-Objekt verfügt über einen epoll und ist einer eigenen Goroutine zugeordnet. Die Anzahl der Goroutinen entspricht der Anzahl der Poll-Objekte. Jedes Poll-Objekt kann mehrere Dateideskriptoren (fd) überwachen.
IO-Lese-/Schreiblogik
- Jedes Poll-Objekt startet eine Goroutine, die kontinuierlich lesbare und beschreibbare Ereignisse auf dem aktuellen epoll abfragt
- Jeder epoll ist mit mehreren fds verknüpft, wobei jedes fd einem Buffer zugeordnet ist
- Wenn ein lesbares Ereignis von einem fd erkannt wird, werden die Daten in den Buffer gelesen
- Die Daten im Buffer werden kontinuierlich abgefragt und verarbeitet. Wenn die Daten vollständig gelesen wurden, wird der GoPoll-Goroutine-Pool für die weitere Verarbeitung benachrichtigt
- Die Interaktion mit Kernel-Systemaufrufen wird vollständig von netpoll kontrolliert. Lese- und Schreiboperationen der Userspace-Conn operieren nur auf dem gemeinsam genutzten Buffer.
Vor- und Nachteile
Vorteile: Unterstützt eine stärkere Hochparallelitätsfähigkeit. - (1) Kontinuierige Abfrage und Verarbeitung der Buffer-Daten, es gibt keine Situation, in der Daten nicht verarbeitet werden. - (2) Eine Goroutine verwaltet mehrere Verbindungen. Selbst bei sehr vielen Verbindungen ist der Aufwand für Ressourcenplanung und Kontextwechsel gering. - (3) Unterstützt gemeinsame Buffer zwischen Benutzer und Kernel, reduziert eine Datenkopieroperation und erhöht die Effizienz.
Nachteile: Benötigt mehr Speicher.
