Réponses:
Ce n'est pas possible , dans un souci de simplification de Redis .
Quoth Antirez, créateur de Redis:
Bonjour, il n'est pas possible d'utiliser une clé de niveau supérieur différente pour ce champ spécifique, ou de stocker avec le champ un autre champ avec une heure d'expiration, de récupérer les deux et de laisser l'application comprendre si elle est toujours valide ou non basée sur heure actuelle.
Redis ne prend pas en charge TTL
les hachages autres que la clé supérieure, qui expirerait tout le hachage. Si vous utilisez un cluster partitionné, vous pouvez utiliser une autre approche. Cette approche ne peut pas être utile dans tous les scénarios et les caractéristiques de performance peuvent différer de celles attendues. Encore à mentionner:
Lors d'un hachage, la structure ressemble essentiellement à:
hash_top_key
- child_key_1 -> some_value
- child_key_2 -> some_value
...
- child_key_n -> some_value
Puisque nous voulons ajouter TTL
aux clés enfants, nous pouvons les déplacer vers les clés supérieures. Le point principal est que la clé doit maintenant être une combinaison de hash_top_key
et de clé enfant:
{hash_top_key}child_key_1 -> some_value
{hash_top_key}child_key_2 -> some_value
...
{hash_top_key}child_key_n -> some_value
Nous utilisons la {}
notation à dessein. Cela permet à toutes ces clés de tomber dans le même hash slot
. Vous pouvez en savoir plus ici: https://redis.io/topics/cluster-tutorial
Maintenant, si nous voulons faire la même opération de hachage, nous pourrions faire:
HDEL hash_top_key child_key_1 => DEL {hash_top_key}child_key_1
HGET hash_top_key child_key_1 => GET {hash_top_key}child_key_1
HSET hash_top_key child_key_1 some_value => SET {hash_top_key}child_key_1 some_value [some_TTL]
HGETALL hash_top_key =>
keyslot = CLUSTER KEYSLOT {hash_top_key}
keys = CLUSTER GETKEYSINSLOT keyslot n
MGET keys
L'intéressant ici est HGETALL
. Nous obtenons hash slot
d'abord les clés de tous nos enfants. Ensuite, nous obtenons les clés pour cela hash slot
et enfin nous récupérons les valeurs. Nous devons faire attention ici car il pourrait y avoir plus que des n
clés pour cela hash slot
et aussi il pourrait y avoir des clés qui ne nous intéressent pas, mais elles ont les mêmes hash slot
. Nous pourrions en fait écrire un Lua
script pour effectuer ces étapes sur le serveur en exécutant une commande EVAL
ou EVALSHA
. Encore une fois, vous devez prendre en considération les performances de cette approche pour votre scénario particulier.
Quelques références supplémentaires:
Il existe un framework Java Redisson qui implémente un Map
objet de hachage avec prise en charge de l'entrée TTL. Il utilise des objets hmap
et zset
Redis sous le capot. Exemple d'utilisation:
RMapCache<Integer, String> map = redisson.getMapCache('map');
map.put(1, 30, TimeUnit.DAYS); // this entry expires in 30 days
Cette approche est très utile.
Ceci est possible dans KeyDB qui est un Fork de Redis. Parce que c'est une fourche, elle est entièrement compatible avec Redis et fonctionne comme un remplacement.
Utilisez simplement la commande EXPIREMEMBER. Il fonctionne avec des ensembles, des hachages et des ensembles triés.
EXPIREMEMBER keyname sous-clé [heure]
Vous pouvez également utiliser TTL et PTTL pour voir l'expiration
Sous-clé de nom de clé TTL
Plus de documentation est disponible ici: https://docs.keydb.dev/docs/commands/#expiremember
Concernant une implémentation NodeJS, j'ai ajouté un expiryTime
champ personnalisé dans l'objet que je sauvegarde dans le HASH. Ensuite, après une période spécifique, j'efface les entrées HASH expirées en utilisant le code suivant:
client.hgetall(HASH_NAME, function(err, reply) {
if (reply) {
Object.keys(reply).forEach(key => {
if (reply[key] && JSON.parse(reply[key]).expiryTime < (new Date).getTime()) {
client.hdel(HASH_NAME, key);
}
})
}
});
Array.filter
pour créer un tableau de keys
à supprimer du hachage, puis le transmettre client.hdel(HASH_NAME, ...keys)
en un seul appel.
const keys = Object.keys(reply).filter(key => reply[key] && JSON.parse(reply[key]).expiryTime < Date.now()); client.hdel(HASH_NAME, ...keys);
Vous pouvez. Voici un exemple.
redis 127.0.0.1:6379> hset key f1 1
(integer) 1
redis 127.0.0.1:6379> hset key f2 2
(integer) 1
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> expire key 10
(integer) 1
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> hvals key
Utilisez EXPIRATION ou EXPIREAT commande.
Si vous souhaitez faire expirer des clés spécifiques dans le hachage, plus de 1 mois. Ce n'est pas possible. La commande Redis expire concerne toutes les clés du hachage. Si vous définissez une clé de hachage quotidienne, vous pouvez définir une durée de vie des clés.
hset key-20140325 f1 1
expire key-20140325 100
hset key-20140325 f1 2
Vous pouvez stocker les clés / valeurs dans Redis différemment pour y parvenir, en ajoutant simplement un préfixe ou un espace de noms à vos clés lorsque vous les stockez, par exemple "hset_"
Obtenir une clé / valeur GET hset_key
égale àHGET hset key
Ajouter une clé / valeur SET hset_key value
égale àHSET hset key
Obtenez toutes les clés KEYS hset_*
égales àHGETALL hset
Obtenir toutes les valeurs doit être effectué en 2 opérations, obtenir d'abord toutes les clés, KEYS hset_*
puis obtenir la valeur de chaque clé
Ajoutez une clé / valeur avec TTL ou expirez qui est le sujet de la question:
SET hset_key value
EXPIRE hset_key
Remarque : KEYS
recherchera la correspondance de la clé dans toute la base de données, ce qui peut affecter les performances, en particulier si vous avez une grande base de données.
Remarque:
KEYS
recherchera la correspondance de la clé dans toute la base de données, ce qui peut affecter les performances, en particulier si vous avez une grande base de données. alors SCAN 0 MATCH hset_*
peut - être mieux aussi longtemps qu'il ne bloque pas le serveur mais la performance est un problème dans le cas de la grande base de données.
Vous pouvez créer une nouvelle base de données pour stocker séparément ces clés que vous souhaitez expirer, surtout s'il s'agit d'un petit jeu de clés.
Merci à @DanFarrell qui a souligné le problème de performance lié à
KEYS
hashset
.. get O (1) set O (1) get all O (n)
O(n)
pour le nombre de choses dans l'ensemble, KEYS
pour le nombre de choses dans la DB.
scan 0 match namespace:*
pourrait être mieux tant que cela ne bloque pas le serveur
Nous avons eu le même problème discuté ici.
Nous avons un hachage Redis, une clé pour les entrées de hachage (paires nom / valeur), et nous devions conserver des délais d'expiration individuels pour chaque entrée de hachage.
Nous avons implémenté cela en ajoutant n octets de données de préfixe contenant des informations d'expiration codées lorsque nous écrivons les valeurs d'entrée de hachage, nous définissons également la clé pour qu'elle expire au moment contenu dans la valeur en cours d'écriture.
Ensuite, en lecture, nous décodons le préfixe et vérifions l'expiration. Il s'agit d'une surcharge supplémentaire, cependant, les lectures sont toujours O (n) et la clé entière expirera lorsque la dernière entrée de hachage aura expiré.
Vous pouvez utiliser les notifications de l'espace clé Redis en utilisant psubscribe
et "__keyevent@<DB-INDEX>__:expired"
.
Avec cela, chaque fois qu'une clé expirera, vous recevrez un message publié sur votre connexion redis.
En ce qui concerne votre question, vous créez une clé temporaire "normale" en utilisant set
un délai d'expiration en s / ms. Il doit correspondre au nom de la clé que vous souhaitez supprimer de votre ensemble.
Comme votre clé temporaire sera publiée sur votre connexion redis en tenant le "__keyevent@0__:expired"
quand elle a expiré, vous pouvez facilement supprimer votre clé de votre jeu d'origine car le message aura le nom de la clé.
Un exemple simple en pratique sur cette page: https://medium.com/@micah1powell/using-redis-keyspace-notifications-for-a-reminder-service-with-node-c05047befec3
doc: https://redis.io/topics/notifications (recherchez le drapeau xE)
Vous pouvez utiliser Sorted Set dans redis pour obtenir un conteneur TTL avec horodatage comme score. Par exemple, chaque fois que vous insérez une chaîne d'événement dans l'ensemble, vous pouvez définir son score sur l'heure de l'événement. Ainsi, vous pouvez obtenir des données de n'importe quelle fenêtre de temps en appelant
zrangebyscore "your set name" min-time max-time
De plus, nous pouvons faire expirer en utilisant zremrangebyscore "your set name" min-time max-time
pour supprimer les anciens événements.
Le seul inconvénient ici est que vous devez faire le ménage à partir d'un processus externe pour maintenir la taille de l'ensemble.
Vous pouvez facilement expirer les hachages Redis, par exemple en utilisant python
import redis
conn = redis.Redis('localhost')
conn.hmset("hashed_user", {'name': 'robert', 'age': 32})
conn.expire("hashed_user", 10)
Cela expirera toutes les clés enfants dans hash hashed_user après 10 secondes
idem de redis-cli,
127.0.0.1:6379> HMSET testt username wlc password P1pp0 age 34
OK
127.0.0.1:6379> hgetall testt
1) "username"
2) "wlc"
3) "password"
4) "P1pp0"
5) "age"
6) "34"
127.0.0.1:6379> expire testt 10
(integer) 1
127.0.0.1:6379> hgetall testt
1) "username"
2) "wlc"
3) "password"
4) "P1pp0"
5) "age"
6) "34"
après 10 secondes
127.0.0.1:6379> hgetall testt
(empty list or set)
hset
enfant pas le plein hset
.