Der Linux-Kernel 3.9 bietet ein interessantes neues Feature, die Socket-Option SO_REUSEPORT. Damit ist es z. B. auf einem aktuellen SLES 12 SP1 System möglich, zwei Prozesse auf demselben Port zu betreiben.
Folgendes Beispiel mit netcat verdeutlicht das Verhalten:
Doch wozu soll das gut sein?
Wichtig ist zu wissen, dass der Kernel ein Connection Load-Balancing zwischen den einzelnen Sockets durchführt, die auf dem selben Port lauschen. Diese Sockets können von Prozessen oder Threads erstellt werden, die unter der gleichen effektiven UID laufen und explizit die Option SO_REUSEPORT setzen. In dem Beispiel würden die eingehenden Verbindungen dementsprechend auf die beiden nc-Prozesse verteilt werden.
Nutzbar ab Apache 2.4.17
Apache kann das neue Feature seit der Version 2.4.17 über die Direktive ListenCoresBucketsRatio nutzen bzw. der Listening-Socket des Hauptprozesses wird standardmäßig mit der Option SO_REUSEPORT erstellt. Falls das Akzeptieren neuer Verbindungen der Bottleneck ist und der Apache auf einem System mit vielen CPUs läuft, kann ListenCoresBucketsRatio die Skalierbarkeit verbessern. Für den sinnvollen Einsatz des Features sollten mindestens 16 CPUs zur Verfügung stehen.
Die Direktive gibt das Verhältnis zwischen CPUs und zu erstellenden Listening-Buckets an. Es müssen mindestens doppelt so viele CPUs im Vergleich zur angegebenen Ratio existieren. Somit ist es notwendig, ListenCoresBucketsRatio an die Hardware-Vorgaben des jeweiligen Systems anzupassen.
NGINX und Performance-Vorteile
Nicht nur Apache, sondern auch andere Webserver können das Kernel-Feature nutzen. Bei NGINX z. B. kann der listen-Direktive die Option reuseport mitgegeben werden, wodurch für jeden Worker-Prozess ein eigener Listening-Socket erstellt wird. In einer optimalen Umgebung kann unter Verwendung der Option die Anzahl der Requests, die verarbeitet werden können, verdreifacht werden.
Rolling Updates
Zu den möglichen Performance-Verbesserungen ermöglicht die neuen Socket-Option Rolling Updates (Updates ohne Downtime).
Folgendes Szenario ist mit dem Apache denkbar. Dank der standardmäßig (falls möglich) gesetzten Option, kann ein zweiter Apache mit einer neueren Version aber gleicher Konfiguration auf dem selben Port gestartet werden. Dieser wird vom Kernel sofort in das Load-Balancing einbezogen. Treten keine Fehler auf, kann der alte Apache gestoppt werden und die neue Version wurde ohne Unterbrechung implementiert.
Quellen:
2. https://lwn.net/Articles/542629/
3. https://httpd.apache.org/docs/trunk/en/mod/mpm_common.html#listencoresbucketsratio
4. https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/