webentwicklung-frage-antwort-db.com.de

Redis Pubsub und Message Queuing

Meine allgemeine Frage lautet: Was passiert mit Redis for PubSub mit Nachrichten, wenn Publisher Nachrichten schneller in einen Kanal pushen, als Abonnenten sie lesen können?

Nehmen wir zum Beispiel an, ich hätte:

  • Ein einfacher Herausgeber, der Nachrichten mit einer Geschwindigkeit von 2 msg/s veröffentlicht.
  • Ein einfacher Teilnehmer liest Nachrichten mit einer Geschwindigkeit von 1 msg/s.

Ich gehe naiv davon aus, dass der Abonnent nur 50% der auf Redis veröffentlichten Nachrichten sieht. Um diese Theorie zu testen, habe ich zwei Skripte geschrieben:

pub.py

queue = redis.StrictRedis(Host='localhost', port=6379, db=0)
channel = queue.pubsub()

for i in range(10): 
    queue.publish("test", i)
    time.sleep(0.5)

sub.py

r = redis.StrictRedis(Host='localhost', port=6379, db=0)
p = r.pubsub()
p.subscribe('test')

while True:
    message = p.get_message()
    if message:
        print "Subscriber: %s" % message['data']
    time.sleep(1)

Ergebnisse

  • Als ich zuerst sub.py, Unmittelbar gefolgt von pub.py, Ausführte, stellte ich fest, dass sub.py Tatsächlich alle Meldungen (1-10) nacheinander mit einer Verzögerung von 1 Sekunde anzeigte zwischen. Meine ursprüngliche Annahme war falsch, Redis stellt Nachrichten in die Warteschlange. Weitere Tests erforderlich.
  • Als ich zuerst pub.py Ausgeführt habe und dann 5 Sekunden gewartet habe, bevor ich sub.py Ausgeführt habe, habe ich festgestellt, dass sub.py Nur die zweite Hälfte der Nachrichten anzeigt (5-10). Ich hätte das ursprünglich angenommen, aber angesichts meiner vorherigen Ergebnisse hätte ich gedacht, dass Nachrichten in der Warteschlange stecken, was mich zu folgendem Schluss führte ...

Schlussfolgerungen

  • Der Redis-Server scheint Nachrichten für jeden Client und für jeden Kanal in die Warteschlange zu stellen.
  • Solange ein Client zuhört, spielt es keine Rolle, wie schnell er Nachrichten liest. Solange eine Verbindung besteht, bleiben Nachrichten für diesen Client und diesen Kanal in der Warteschlange.

Restliche Fragen

  • Sind diese Schlussfolgerungen gültig?
  • Wenn ja, wie lange bleiben Client-/Kanalnachrichten in der Warteschlange?
  • Wenn ja, gibt es einen redis-cli info - Befehl, um zu sehen, wie viele Nachrichten in der Warteschlange stehen (für jeden Client/Kanal)?
47
Marco Benvoglio

Die Tests sind gültig, aber die Schlussfolgerungen sind teilweise falsch.

Redis stellt in Pub/Sub-Kanälen keine Warteschlangen. Im Gegenteil, es wird tendenziell das Element aus dem Publisher-Socket gelesen und in alle Subscriber-Sockets geschrieben, idealerweise in derselben Iteration der Ereignisschleife. In Redis-Datenstrukturen wird nichts aufbewahrt.

Nun, wie Sie gezeigt haben, gibt es immer noch eine Art Pufferung. Dies liegt an der Verwendung von TCP/IP-Sockets und Redis-Kommunikationspuffern.

Sockets haben Puffer und natürlich TCP verfügt über einige Flusssteuerungsmechanismen. Dadurch wird der Datenverlust bei vollen Puffern vermieden. Wenn ein Abonnent nicht schnell genug ist, sammeln sich Daten in seinem Socket an buffer. Wenn es voll ist, blockiert TCP die Kommunikation und verhindert, dass Redis weitere Informationen in den Socket schiebt.

Redis verwaltet auch Ausgabekommunikationspuffer (über den Sockets), um mit dem Redis-Protokoll formatierte Daten zu generieren. Wenn der Ausgabepuffer des Sockets voll ist, markiert die Ereignisschleife den Socket als nicht beschreibbar und die Daten verbleiben in den Ausgabepuffern von Redis.

Vorausgesetzt, die TCP - Verbindung ist noch gültig, können die Daten sehr lange in den Puffern verbleiben. Jetzt sind sowohl der Socket - als auch der Redis - Ausgabepuffer gebunden. Wenn die Abonnenten wirklich zu langsam sind, und Wenn sich viele Daten ansammeln, wird Redis letztendlich die Verbindung zu den Abonnenten schließen (als Sicherheitsmechanismus).

Standardmäßig hat Redis für Pub/Sub ein Soft-Limit von 8 MB und ein Hard-Limit von 32 MB pro Verbindungspuffer. Wenn der Ausgabepuffer das harte Limit erreicht oder länger als 60 Sekunden zwischen dem weichen und dem harten Limit bleibt, wird die Verbindung mit dem langsamen Teilnehmer geschlossen.

Die Anzahl der ausstehenden Nachrichten zu kennen ist nicht einfach. Dies kann anhand der Größe der ausstehenden Informationen in den Socket-Puffern und den Redis-Ausgabepuffern bewertet werden.

Für Redis-Ausgabepuffer können Sie den Befehl CLIENT LIST (von redis-cli) verwenden. Die Größe des Ausgabepuffers wird in den Feldern obl und oll (in Bytes) zurückgegeben.

Für Socket-Puffer gibt es keinen Redis-Befehl. Unter Linux ist es jedoch möglich, ein Skript zur Interpretation des Inhalts der Datei/proc/net/tcp zu erstellen. Siehe ein Beispiel hier . Dieses Skript muss wahrscheinlich an Ihr System angepasst werden.

87
Didier Spezia