Wie implementiert Redis die Nachrichtenwarteschlange und die verzögerte Nachrichtenwarteschlange? Der folgende Artikel stellt Ihnen die Implementierungsmethoden der Nachrichtenwarteschlange und der verzögerten Nachrichtenwarteschlange in Redis vor. Ich hoffe, er wird Ihnen hilfreich sein!
Wenn es um Redis geht, denken vielleicht mehr Leute an die Verwendung als Cache. Tatsächlich kann Redis auch einige einfache Nachrichtenwarteschlangenzwecke implementieren. Wir können die Listendatenstruktur verwenden, um die Warteschlange zu implementieren. [Verwandte Empfehlungen: Redis-Video-Tutorial]
lpush (Linksdruck)
wird von der linken Seite der Warteschlange gespeichert
rpush (Rechtsdruck)
wird von der rechten Seite gespeichert Seite der Warteschlange
lpop (linker Pop)
Von der linken Seite der Warteschlange herausziehen
rpop (rechter Pop)
Von der rechten Seite der Warteschlange herausziehen
Die oben genannten vier Befehle können eine Liste erstellen Helfen Sie uns bei der Implementierung von Warteschlangen oder Stapeln und den Merkmalen von Warteschlangen. Es gilt: „First in, first out“ und die Eigenschaft des Stapels ist „First in, last out“,
Die Warteschlangenimplementierung kann also lpush + rpop oder rpush + lpop verwenden,
Die Stack-Implementierung ist lpush + lpop oder rpush + rpop.
Der Produzent veröffentlicht Nachrichten Als Produzent veröffentlichen Sie Nachrichten. Der Verbraucher konsumiert Nachrichten. Da der Produzent rpush verwendet, muss der Verbraucher lpop verwenden in der Reihenfolge von 1 bis 5 auslesen und in der Reihenfolge vorlesen. Am Ende befinden sich keine Nachrichten in der Warteschlange und das Popup ist immer leer
Leeres AbfrageproblemVerwenden Sie lpop, um oben zu konsumieren Wenn Sie eine Nachricht öffnen, können Sie sehen, dass wir jedes Mal, wenn wir zum Pop gehen, eine leere Nachricht lesen, wenn es sich um einen manuellen Ausführungsbefehl handelt. Wenn es sich jedoch um ein Programm mit geschriebenem Code handelt, ist dies der Fall Wird weiterhin Pop-Daten (Abrufen von Daten) ausführen, führt dies zu leeren Abfragen (nutzloses Lesen), was nicht nur den CPU-Verbrauch des Clients erhöht, sondern auch die QPS von Redis erhöht und immer noch ein nutzloser Vorgang ist Infolgedessen reagiert der Zugriff anderer Clients auf Redis nur langsam. Lösung A (Ruhezustand)
Diese Lösung weist auch Mängel auf, d. h. die Verzögerung beim Nachrichtenverbrauch nimmt zu. Wenn nur ein Verbraucher vorhanden ist, beträgt die Verzögerung 1 Sekunde, d Es gibt Neuigkeiten und es muss immer noch bis zum Aufwachen 1 Sekunde warten, bevor es konsumiert wird.
Wenn es mehrere Verbraucher gibt, verringert sich die Latenz, da die Schlafzeit jedes Verbrauchers aufgeteilt ist. Gibt es jedoch einen besseren Weg, dies zu erreichen? fast 0 Latenz? Lösung B (Blockieren des Lesens) Wenn sich keine Daten in der Warteschlange befinden, wird sie sofort beantwortet und liest die Daten. Daher kann die Verwendung von blpop/brpop als Ersatz für lpop/rpop das Problem der Nachrichtenverzögerung lösen um 3 Attribute zur Warteschlange hinzuzufügen, 6, 7, 8 Verwenden Sie blpop, um die Warteschlange zu lesen. Wenn nach dieser Zeit keine Nachricht vorliegt, wird Null zurückgegeben. Zu diesem Zeitpunkt können Sie den BLPOP-Vorgang weiterhin wiederholen Das Problem der automatischen Trennung inaktiver Verbindungen zum Blockieren von LesevorgängenWenn der Client blockierende Lesevorgänge verwendet, wird der Dienst blockiert behandelt sie im Allgemeinen als eine inaktive Verbindung und trennt sie daher aktiv, um unnötige Verbindungen zu reduzieren, die Ressourcen belegen. Zu diesem Zeitpunkt löst der Client eine Ausnahme aus. Beachten Sie daher, dass Ausnahmen erfasst werden müssen, wenn der Client das blockierende Lesen verwendet Behandeln Sie sie entsprechend, z. B. Versuchen Sie es erneut.
Java-Client implementiert Nachrichtenwarteschlange
Thread.sleep(1000)
Ein weiterer oder mehrere Threads führen den Blpop-Verbrauch durch. Der fertige Code befindet sich unter: https://github.com/qiaomengnan16/redis-demo/tree/main/redis-queue
Publisher
Abonnieren
Die Verzögerungswarteschlange bedeutet, dass die Nachricht nach einer gewissen Zeit vom Verbraucher verbraucht wird und der Verbraucher sie nicht sofort lesen kann, nachdem die Nachricht gesendet wurde Erhalten it,
zset kann uns dabei helfen. Erstens kann zset einen Zeitstempel speichern, sodass wir jedes Mal, wenn wir eine Nachricht veröffentlichen, den aktuellen Zeitstempel plus den verzögerten Zeitstempel verwenden Der Verbraucher ruft die Nachricht ab, fängt die Daten von zset ab und erhält die Nachricht, die der aktuellen Zeit entspricht (d. h. es werden Daten mit einer Punktzahl kleiner oder gleich dem aktuellen Zeitstempel erhalten). Die Punktzahl ist kleiner oder gleich dem aktuellen Zeitstempel dass die Meldung die Zeit erreicht hat. Wenn sie größer ist, bedeutet dies, dass Sie eine Weile warten müssen, bevor Sie sie verwenden.
Tastenbefehle zadd (Herausgeber), zrangebyscore (Abonnent), zrem (Abonnent löscht nach Datenverbrauch)
BefehlsimplementierungWir haben zadd verwendet, um 4 Datenelemente hinzuzufügen, nämlich 1 und 2, Daten, die das können nach 3 Sekunden konsumiert werden (Pseudosprache, das ist eigentlich nur eine Punktzahl), und Kafka, das nach 10 Sekunden konsumiert werden kann,
Wenn es die dritte Sekunde erreicht hat, nehmen wir den Wert in zset, der größer ist kleiner oder gleich 1 Die Summe der Sekunden ist kleiner oder gleich 3 Sekunden an Daten, da die Daten in diesem Bereich genau das sind, was wir konsumieren können. Wie Sie sehen, haben wir 3 Datenelemente herausgenommen, die die Bedingungen erfüllen ,
Wenn wir jeweils nur ein Datenelement verbrauchen können, können Sie eine Begrenzungsbeschränkungsbedingung hinzufügen. Sie können das Bild unten sehen, um die ersten Daten herauszunehmen, die verbraucht werden können, redis
Beachten Sie gleichzeitig, dass es sich von den Listendaten lpop/ und blpop unterscheidet (sie löschen automatisch die Daten in der ursprünglichen Warteschlange, wenn sie angezeigt werden).
Obwohl die Daten abgerufen wurden, wenn zrem nicht verwendet wird Um es zu löschen, werden diese Daten weiterhin von anderen gelesen, da sie noch in zset vorhanden sind.
Zrem wurde jedoch möglicherweise von anderen vorbelegt. Im Falle des Löschens (Verbrauchs) muss der Code auch beurteilen, ob die Rückgabe erfolgt Wenn der Wert von zrem größer als 0 ist, können wir feststellen, ob wir diese Nachricht erfolgreich vorweggenommen haben und sie nach dem Erfolg korrekt verarbeiten.
Code-Implementierung
VerlegerAbonnenten
Testen Sie den Verzögerungseffekt
Vollständige Codeadresse: https://github.com/ qiaomengnan16 /redis-demo/tree/main/redis-delayed-queue
Optimierung, implementiert mit LuaEs gibt ein Problem in der oben implementierten Verzögerungswarteschlange, d Wenn Sie so weiterlesen, ist es sehr wahrscheinlich, dass Sie sie mehrere Runden lang nicht abrufen können und die Ressourcen verschwendet werden. Daher können Sie sie mithilfe von Lua-Skripten optimieren Lassen Sie zrangebyscore und zrem zu einer atomaren Operation werden, was bedeutet, dass Multi-Thread-Konflikte vermieden und Ressourcen verschwendet werden können, die nicht abgerufen werden können.
Fazit
Weitere Kenntnisse zum Thema Programmierung finden Sie unter:
Einführung in die Programmierung! !
Das obige ist der detaillierte Inhalt vonEine kurze Diskussion über die Implementierungsmethoden der Nachrichtenwarteschlange und der verzögerten Nachrichtenwarteschlange in Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!