Ich muss alle Schlüssel in Redis Hash ablaufen lassen, die älter als 1 Monat sind.
107
Dies ist nicht möglich , um Redis einfach zu halten .
Quoth Antirez, Schöpfer von Redis:
Hallo, es ist nicht möglich, entweder einen anderen Schlüssel der obersten Ebene für dieses bestimmte Feld zu verwenden oder zusammen mit dem abgelegten anderen Feld mit einer Ablaufzeit zu speichern, beide abzurufen und der Anwendung zu erklären, ob sie noch gültig ist oder nicht aktuelle Uhrzeit.
Redis unterstützt es nicht,
TTL
andere Hashes als den oberen Schlüssel zu verwenden, wodurch der gesamte Hash abläuft. Wenn Sie einen Sharded-Cluster verwenden, können Sie einen anderen Ansatz verwenden. Dieser Ansatz ist möglicherweise nicht in allen Szenarien nützlich, und die Leistungsmerkmale können von den erwarteten abweichen. Noch erwähnenswert:Wenn Sie einen Hash haben, sieht die Struktur im Grunde so aus:
Da wir die untergeordneten
TTL
Schlüssel hinzufügen möchten , können wir sie in die oberen Schlüssel verschieben. Der Hauptpunkt ist, dass der Schlüssel jetzt eine Kombination aus einemhash_top_key
untergeordneten Schlüssel sein sollte:Wir verwenden die
{}
Notation absichtlich. Dadurch können alle diese Schlüssel in dieselbe fallenhash slot
. Weitere Informationen finden Sie hier: https://redis.io/topics/cluster-tutorialWenn wir nun die gleiche Operation von Hashes ausführen möchten, können wir Folgendes tun:
Das Interessante hier ist
HGETALL
. Zuerst bekommen wir diehash slot
Schlüssel für alle unsere Kinder. Dann bekommen wir die Schlüssel für diesen bestimmtenhash slot
und schließlich rufen wir die Werte ab. Wir müssen hier vorsichtig sein, da es dafür mehr als nurn
Schlüssel geben kannhash slot
und es auch Schlüssel geben kann, an denen wir nicht interessiert sind, die aber dieselben habenhash slot
. Wir könnten tatsächlich einLua
Skript schreiben , um diese Schritte auf dem Server auszuführen, indem wir einen BefehlEVAL
oder ausführenEVALSHA
. Auch hier müssen Sie die Leistung dieses Ansatzes für Ihr spezielles Szenario berücksichtigen.Einige weitere Referenzen:
quelle
Es gibt ein Redisson- Java-Framework, das Hash-
Map
Objekte mit TTL-Unterstützung für Einträge implementiert . Es verwendethmap
undzset
Redis Objekte unter der Haube. Anwendungsbeispiel:Dieser Ansatz ist sehr nützlich.
quelle
Dies ist in KeyDB möglich, einer Fork of Redis. Da es sich um eine Gabel handelt, ist sie vollständig mit Redis kompatibel und fungiert als Ersatz.
Verwenden Sie einfach den Befehl EXPIREMEMBER. Es funktioniert mit Sets, Hashes und sortierten Sets.
Sie können auch TTL und PTTL verwenden, um den Ablauf anzuzeigen
Weitere Dokumentation finden Sie hier: https://docs.keydb.dev/docs/commands/#expiremember
quelle
In Bezug auf eine NodeJS-Implementierung habe ich
expiryTime
dem Objekt, das ich im HASH speichere, ein benutzerdefiniertes Feld hinzugefügt. Nach einer bestimmten Zeit lösche ich die abgelaufenen HASH-Einträge mit dem folgenden Code:quelle
Array.filter
ein Arraykeys
zum Löschen aus dem Hash erstellen und dieses dannclient.hdel(HASH_NAME, ...keys)
in einem einzigen Aufruf an übergeben.const keys = Object.keys(reply).filter(key => reply[key] && JSON.parse(reply[key]).expiryTime < Date.now()); client.hdel(HASH_NAME, ...keys);
Sie können. Hier ist ein Beispiel.
Verwenden Sie den Befehl EXPIRE oder EXPIREAT .
Wenn Sie bestimmte Schlüssel im Hash ablaufen lassen möchten, die älter als 1 Monat sind. Das ist nicht möglich. Der Redis Expire-Befehl gilt für alle Schlüssel im Hash. Wenn Sie den täglichen Hash-Schlüssel festlegen, können Sie die Lebensdauer der Schlüssel festlegen.
quelle
Sie können Schlüssel / Werte in Redis anders speichern, um dies zu erreichen, indem Sie Ihren Schlüsseln einfach ein Präfix oder einen Namespace hinzufügen, wenn Sie sie speichern, z. B. "hset_".
Holen Sie sich einen Schlüssel / Wert
GET hset_key
gleichHGET hset key
Fügen Sie einen Schlüssel / Wert hinzu, der
SET hset_key value
gleich istHSET hset key
Holen Sie sich alle Schlüssel
KEYS hset_*
gleichHGETALL hset
Das Abrufen aller Werte sollte in 2 Operationen erfolgen. Holen Sie sich zuerst alle Schlüssel und
KEYS hset_*
dann den Wert für jeden SchlüsselFügen Sie mit TTL einen Schlüssel / Wert hinzu oder verfallen, was das Thema der Frage ist:
Hinweis :
KEYS
Sucht nach Übereinstimmungen mit dem Schlüssel in der gesamten Datenbank, was sich auf die Leistung auswirken kann, insbesondere wenn Sie über eine große Datenbank verfügen.Hinweis:
KEYS
sucht nach Übereinstimmungen mit dem Schlüssel in der gesamten Datenbank, was sich auf die Leistung auswirken kann, insbesondere wenn Sie über eine große Datenbank verfügen. Dies istSCAN 0 MATCH hset_*
möglicherweise besser, solange der Server nicht blockiert wird, die Leistung jedoch bei großen Datenbanken ein Problem darstellt.Sie können eine neue Datenbank erstellen, um diese Schlüssel, die Sie ablaufen lassen möchten, separat zu speichern, insbesondere wenn es sich um kleine Schlüsselsätze handelt.
quelle
hashset
.. get O (1) set O (1) get all O (n)O(n)
für die Anzahl der Dinge in der Menge undKEYS
für die Anzahl der Dinge in der Datenbank .scan 0 match namespace:*
könnte besser sein, solange es den Server nicht blockiertWir hatten das gleiche Problem hier diskutiert.
Wir haben einen Redis-Hash, einen Schlüssel für Hash-Einträge (Name / Wert-Paare), und wir mussten für jeden Hash-Eintrag individuelle Ablaufzeiten festlegen.
Wir haben dies implementiert, indem wir beim Schreiben der Hash-Eintragswerte n Bytes Präfixdaten hinzugefügt haben, die codierte Ablaufinformationen enthalten. Außerdem haben wir den Schlüssel so festgelegt, dass er zu dem Zeitpunkt abläuft, der in dem zu schreibenden Wert enthalten ist.
Dann dekodieren wir beim Lesen das Präfix und prüfen, ob es abgelaufen ist. Dies ist ein zusätzlicher Aufwand, die Lesevorgänge sind jedoch immer noch O (n) und der gesamte Schlüssel läuft ab, wenn der letzte Hash-Eintrag abgelaufen ist.
quelle
Sie können die Redis Keyspace-Benachrichtigungen mit
psubscribe
und verwenden"__keyevent@<DB-INDEX>__:expired"
.Damit erhalten Sie jedes Mal, wenn ein Schlüssel abläuft, eine Nachricht, die auf Ihrer Redis-Verbindung veröffentlicht wird.
In Bezug auf Ihre Frage erstellen Sie im Grunde einen temporären "normalen" Schlüssel
set
mit einer Ablaufzeit in s / ms. Es sollte mit dem Namen des Schlüssels übereinstimmen, den Sie in Ihrem Set löschen möchten.Da Ihr temporärer Schlüssel in Ihrer Redis-Verbindung veröffentlicht wird,
"__keyevent@0__:expired"
wenn er abgelaufen ist, können Sie Ihren Schlüssel einfach aus Ihrem ursprünglichen Satz löschen, da die Nachricht den Namen des Schlüssels enthält.Ein einfaches Beispiel in der Praxis auf dieser Seite: https://medium.com/@micah1powell/using-redis-keyspace-notifications-for-a-reminder-service-with-node-c05047befec3
doc: https://redis.io/topics/notifications (achten Sie auf das Flag xE)
quelle
Sie können Sorted Set in redis verwenden, um einen TTL-Container mit Zeitstempel als Punktzahl zu erhalten. Wenn Sie beispielsweise eine Ereigniszeichenfolge in den Satz einfügen, können Sie die Punktzahl auf die Ereigniszeit festlegen. So können Sie durch Aufrufen Daten aus jedem Zeitfenster abrufen
zrangebyscore "your set name" min-time max-time
Darüber hinaus können wir verfallen, indem wir
zremrangebyscore "your set name" min-time max-time
alte Ereignisse entfernen.Der einzige Nachteil hierbei ist, dass Sie die Reinigung von einem Außenstehenden durchführen müssen, um die Größe des Sets beizubehalten.
quelle
Sie können Redis-Hashes problemlos ablaufen lassen , z. B. mit Python
Dadurch laufen alle untergeordneten Schlüssel in hash hashed_user nach 10 Sekunden ab
das gleiche von redis-cli,
nach 10 Sekunden
quelle
hset
Kind nicht die vollehset
.