2010-10-28 3 views
8

Wir verwenden Redis als Caching-Server und müssen oft mit der Caching-Liste umgehen. Wenn wir einfache Objekte zwischenspeichern, führen wir einen GET aus, und Redis gibt null zurück, wenn das Objekt nicht existiert und wir wissen, dass das Objekt nicht zwischengespeichert ist und aus der Datenbank geladen werden muss.Was ist Best Practice für die Bearbeitung von Listen und Sets in Redis?

Aber wie können wir das gleiche für Listen handhaben - eine leere Liste kann ein gültiger Wert sein. Müssen wir EXISTS aufrufen, um zu prüfen, ob die Liste existiert (aber die Operation 2 statt einer aufruft) oder hat jemand eine bessere Idee, wie man mit diesem Szenario umgeht?

/Danke

Antwort

9

Wenn Sie das unbedingt tun müssen, können Sie beim Erstellen der Liste ein "Sentinel" als erstes Element drücken, das nie entfernt wird. Um dies atomar zu tun, können Sie MULTI/EXEC/WATCH verwenden, aber Watch ist nur in Redis 2.2 verfügbar, das derzeit eine Vorschau ist (auch wenn es ziemlich stabil ist, können Sie es aus dem Github-Master-Zweig holen).

Ich denke in Ihrem Anwendungsfall können Sie auch RPUSHX und LPUSHX, die gegen eine Liste nur dann atomar drücken, wenn es bereits existiert.

Beachten Sie, dass Mittel seit Redis 2.2 zu existieren mindestens 1 Element, um eine Liste zu haben, wie Listen, die Null-Elemente werden automatisch entfernt, für viele gute Gründe erreichen;)

+1

Nach etwas mehr Überlegung denke ich, dass meine Lösung einfach darin besteht, die Liste nicht automatisch zu regenerieren. Mein Anliegen war folgendes: Ich füge einen Datensatz in eine Datenbank ein und füge ihn gleichzeitig einer Redis-Liste hinzu. Wenn Redis abstürzen sollte (und vielleicht die letzte Sekunde der Transaktionen verliert) - wie komme ich zu einem Zustand, in dem die Datenbank und Redis wieder synchronisiert sind? Ich denke, dass ich auf eine Lösung gelandet bin, die bedeutet, dass, wenn Redis stürzen sollte, die Situation manuell durch erneutes Synchronisieren der Listen aus der Datenbank wiederhergestellt werden muss. Oh - und danke für die nette Arbeit :-) – Micael

+0

+1 für die richtige Antwort. Aber könnten Sie mich auf Ihre "guten Gründe" hinweisen? Leere Sätze und Listen unterscheiden sich von nicht existierenden. – Crisfole

-1

Wenn Sie PHP verwenden, würde ich den Rückgabewert einer Variablen zuweisen und dann prüfen, ob es ein Array ist. (Dies ist, wie es funktioniert die Predis-Bibliothek)

$res = $redis->get('Key'); 
if(is_array($res)) 
    do code here 
3

Leider Liste/set Abrufbefehle wie LRANGE und SMEMBERS scheinen nicht zwischen einer leeren Liste/Set und einer nicht vorhandenen Liste/set zu unterscheiden.

Also, wenn Sie unbedingt zwischen den beiden Fällen unterscheiden müssen, müssen Sie zuerst ein EXISTS machen. Versuchen Sie, Ihre Befehle für eine bessere Leistung zu pipelineen. Die meisten Redis-Client-Bibliotheken unterstützen Pipelining.

Oder Sie könnten Ihre Caching-Strategie überdenken, so dass Sie sie nicht unterscheiden müssen.

+0

Seit v2.0 redis behandelt leere Listen , SETs, ZSETs und HASHEs genauso wie nicht existierende. Wenn Sie alle Elemente aus einer Liste entfernt haben, gibt der EXISTS-Befehl false zurück! –

+0

@Ludger Sprenker Wow, das wusste ich nicht! Ich habe das vorher nur mit 1.2.6 getestet. Dies ist Micaels Caching-Strategie. – kijin

Verwandte Themen