Welche Skalierbarkeitsprobleme gibt es bei Pub/Sub-Servern?

Welche Skalierbarkeitsprobleme gibt es bei Pub/Sub-Servern?

Ich möchte einen Pub/Sub-Dienst mit WebSockets einrichten. Soweit ich weiß, werden die Skalierbarkeitsengpässe hauptsächlich beim Speicher liegen, der sich darauf auswirkt, wie viele Sockets gleichzeitig geöffnet werden können. Daher halte ich es für sinnvoll, dies von den anderen Servern abzuspalten, auf denen Dienste wie APIs ausgeführt werden. Ist das richtig? Ich könnte mir vorstellen, dass Speicher beim Hosting teurer ist als Rechenleistung. Gibt es also Best Practices, um diesen Servertyp hinsichtlich Skalierbarkeit und Kosten zu optimieren?

Das Ziel besteht darin, dem Benutzer dieser Webanwendung Echtzeit-Updates bereitzustellen, wenn Systeme im Feld neue Daten einchecken, ohne das Backend regelmäßig abfragen zu müssen. Wir möchten unsere Serverkosten jedoch nicht verdoppeln, da sich das sonst möglicherweise nicht lohnt. Für unsere aktuellen API-Server verwenden wir AWS EC2 mit Lastenausgleich und automatischer Skalierung.

Antwort1

Der tatsächliche Speicherverbrauch eines einzelnen Sockets ist nicht so hoch.

Speicherhungrig ist allerdings die Frage, welcher Client an welchen Updates interessiert ist und welcher Client ein bestimmtes Update bereits erhalten hat.

Bei einer primitiven Implementierung (d. h. unter Verwendung des Netzwerkstapels des Betriebssystems) wird der letztere Status in Form von Ausgangspuffern gespeichert. Wenn also ein Update an 10.000 Clients gesendet wird, werden die Daten 10.000 Mal kopiert und jede Kopie an eine Ausgangswarteschlange angehängt. Dort werden sie mit den erforderlichen Headern (die den Status pro Verbindung enthalten) ergänzt. Anschließend wird ein Deskriptor für die Hardware erstellt, der sie anweist, ein Paket zu senden, das eine Verkettung der Header und der Nutzlast darstellt.

Die Kopie der Nutzlast pro Client wird im Speicher aufbewahrt, bis sie vom Client bestätigt wird. Daher stammen die Speicheranforderungen. Dieser Speicher kann nicht ausgelagert werden, sodass bei anderen Anwendungen Speicher- und Cachedruck entsteht.

Es gibt Implementierungen, die Teile des Netzwerkstapels im Serverprogramm selbst implementieren und die Kopien durch Referenzzählung oder Neuerstellung der Nutzlasten bei Bedarf vermeiden können. Dadurch wird der Speicherverbrauch deutlich gesenkt, aber für eine echte Skalierbarkeit ist eine Menge kniffliger Codierung erforderlich. Insbesondere Multi-Socket-Server werfen hier einige interessante Probleme auf, die der Netzwerkstapel des Betriebssystems bereits zu umgehen weiß.

Diese Optionen haben Sie

  1. Führen Sie den Pub/Sub-Dienst auf demselben Server wie die App aus.
  2. Betreiben Sie den Pub/Sub-Dienst auf einem dedizierten Server mit OS-Netzwerk
  3. Führen Sie den Pub/Sub-Dienst auf einem dedizierten Server mit benutzerdefiniertem Netzwerk aus.
  4. den Pub/Sub-Dienst auf mehreren dedizierten Servern ausführen

sind Ihre Eskalationsstrategie, wenn der Service wächst. Der Wechsel von Shared zu Dedicated erfordert nicht viel Planung und kann nach Bedarf durchgeführt werden. Sobald dies geschehen ist, ist es an der Zeit, die weiteren Schritte vorzubereiten.

Durch die Skalierung auf mehrere Server wird Nichtdeterminismus in Ihr System eingeführt, da die Clients Updates in unterschiedlicher Reihenfolge erhalten können. Damit dieser Skalierungsschritt erfolgreich ist, müssen Ihre Clients sich dessen bewusst sein und eine konsistente Ansicht darstellen können. Ob das trivial oder schwierig ist, hängt von Ihrer tatsächlichen Anwendung ab.

kurz und knapp:keine Notwendigkeit, vorzeitig zu optimieren. Teilen Sie den Dienst so auf, dass der erste Skalierungsschritt eine einfache Konfigurationsänderung ist, und beginnen Sie mit der Optimierung, sobald dies geschehen ist.

verwandte Informationen