23.042014

Redis als Queue

Heute möchte ich die Möglichkeit vorstellen, wie man mit Redis relative einfach eine Queue implementieren kann...

Vermutlich hat der ein oder andere Softwareentwickler schon einmal vor dem gleichen Problem gestanden. Er möchte etwas tracken, weil aus den gesammelten Daten Auswertungen erstellt werden sollen. Als einfache Lösung kann man direkt mit der Datenbank arbeiten, um die Daten aufzunehmen, oder zu aktualisieren. Dies funktioniert vielleicht solange, wie wenig Traffic vorliegt, ein Webserver betrieben wird und es nicht zu blockierenden Statements kommt. Sobald aber der Traffic oder auch die Anzahl der Webserver steigt, steigt auch die Gefahr, dass die Datenbankoperationen sich blockierend auswirken.

Was macht man nun in solch einem Fall?

Klar, man kann jetzt natürlich ein richtiges Queue-System mit z.B. RabbitMQ aufsetzen, aber dies erscheint mir für ein simples Tracking doch deutlich zu "overpowered" zu sein. Mein Vorschlag in diesem Fall ist der Datentype Lists von Redis. Bei Lists handelt es sich um eine einfache Liste von Strings, die nach dem Aufnahmezeitpunkt sortiert werden. Man kann hier Elemente entweder am Anfang der Liste hinzufügen oder am Ende. Für mein Beispiel werde ich die Liste wie einen Trichter verwerden. Neue Elemente werden immer vorne angstellt und die abzuarbeitenden werden vom Ende der Liste genommen.

Wie erzeuge ich nun meine Queue?

Für mein Beispiel verwende ich den Redis-Client auf der Commandozeile. Je nach Programmiersprache gibt es unterschiedliche Client-Implementierungen, auf die man das Vorgehen übertragen kann.

Als erstes wollen wir mal ein paar Daten in unsere Queue aufnehmen. Hierzu legen wir zuerst einmal den Namen der Queue (my_test_queue) fest. Der Name der Queue ist auch gleichzeitig der Identifier der Liste in Redis:


redis-cli lpush my_test_queue "{'object_id': 1, 'view': 1: 'created': '2014-04-23'}"

Dieser Befehl fügt nun unserer Queue den Eintrag hinzu, dass für das Objekt 1 eine View vorliegt.
Um zu kontrollieren, wieviele Elemente in der Queue vorhanden sind, lässt man sich einfach die Länge der Liste ausgeben:


redis-cli llen my_test_queue

Somit haben wir schonmal zwei Befehle um unsere Queue anzusprechen.

Wie kann ich nun mit den Daten der Queue arbeiten?

Um nun mit unseren Daten an einer zentralen Stelle arbeiten zu können, müssen wir ja nun die Daten auslesen. Hierzu holen wir uns nun ein Element vom Ende der Liste.


redis-cli rpop my_test_queue

Die Rückgabe können wir nun nach unserem Belieben verarbeiten.

Ist das jetzt schon eine richtige Queue?

Nicht ganz würde ich jetzt mal sagen. In unserem Beispiel würde jetzt lediglich immer nur ein Element aus der Liste herausgeholt werden und dann wäre auch schon Ende. Um als Queue zu funktionieren sollte man beim Verarbeiten der Daten sowohl mit dem Auslesen, als auch dem Bestimmen der Länge arbeiten. Hierzu baut man sich eine Schleife, die solange abzuarbeitende Elemente aus der Liste herausholt, wie Elemente in der Liste vorhanden sind. Sind keine Elemente mehr vorhanden, dann ist die Queue somit für das erste abgearbeitet. Als weitere Optimierung erzeugt man nun noch einen Croneintrag und lässt die Abarbeitung zum Beispiel alle 5 Minuten wiederholen. Schon ist die eigene einfache Queue fertig.