Je dois expirer toutes les clés de redis hash, qui sont plus vieilles que 1 mois.
Cela n’est pas possible , dans l’intérêt de garder Redis simple .
Quoth Antirez, créateur de Redis:
Bonjour, ce n'est pas possible, utilisez une clé de niveau supérieur différente pour cela champ spécifique, ou stocker avec le champ déposé un autre champ avec un expirer le temps, aller chercher les deux, et laisser l'application comprendre si c'est toujours valable ou non basé sur l'heure actuelle.
Il existe un framework Redisson Java qui implémente un objet hash Map
avec le support d'entrée TTL Il utilise les 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.
Pour ce faire, vous pouvez stocker les clés/valeurs dans Redis différemment, 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
Obtenir toutes les clés KEYS hset_*
est égal à 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 expire 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 que SCAN 0 MATCH hset_*
pourrait être préférable tant qu’il ne bloque pas le serveur mais que les performances restent un problème pour les bases de données volumineuses.
Vous pouvez créer une nouvelle base de données pour stocker séparément ces clés que vous voulez expirer, en particulier s’il s’agit d’un petit jeu de clés.
Merci à @DanFarrell qui a mis en évidence le problème de performance lié à
KEYS
Vous pouvez expirer Redis hachez facilement, par exemple en utilisant python
import redis
conn = redis.Redis('localhost')
conn.hmset("hashed_user", {'name': 'robert', 'age': 32})
conn.expire("hashed_user", 10)
Ceci expirera toutes les clés enfant 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)
En ce qui concerne une implémentation de NodeJS, j'ai ajouté un champ expiryTime
personnalisé dans l'objet que j'enregistre dans le hachage. Puis, après une période donnée, j'efface les entrées HASH expirées à l'aide du 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);
}
})
}
});
Redis ne prend pas en charge l’ajout de TTL
sur des hachages autres que la touche supérieure, ce qui expirerait tout le hachage. Si vous utilisez un cluster partagé, vous pouvez utiliser une autre approche. Cette approche pourrait ne pas être utile dans tous les scénarios et les caractéristiques de performance pourraient différer de celles attendues. Encore à noter:
Lorsque vous avez un hachage, la structure ressemble en gros à:
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 en haut des clés. Le point principal est que la clé devrait 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 lire plus à ce sujet 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
Ce qui est intéressant ici est HGETALL
. Nous obtenons d’abord le hash slot
pour toutes les clés de nos enfants. Ensuite, nous obtenons les clés pour ce hash slot
et enfin, nous récupérons les valeurs. Nous devons faire attention ici car il pourrait y avoir plus que n
clés pour ce hash slot
et il pourrait aussi y avoir des clés qui ne nous intéressent pas mais qui ont le même hash slot
. Nous pourrions en fait écrire un script Lua
pour effectuer ces opérations sur le serveur en exécutant une commande EVAL
ou EVALSHA
. Encore une fois, vous devez prendre en compte les performances de cette approche pour votre scénario particulier.
Quelques autres références:
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 EXPIRE ou EXPIREAT command.
Si vous voulez expirer des clés spécifiques dans le hachage plus vieux que 1 mois. Cela n’est pas possible . La commande Redis expire concerne toutes les clés du hash . 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 utiliser Sorted Set in redis pour obtenir un conteneur TTL avec l'horodatage comme partition. Par exemple, chaque fois que vous insérez une chaîne d'événement dans le jeu, vous pouvez définir son score à l'heure de l'événement. Ainsi, vous pouvez obtenir des données de n'importe quelle fenêtre 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 conserver la taille de l'ensemble.
Vous pouvez utiliser les notifications Redis Keyspace en utilisant psubscribe
et "__keyevent@<DB-INDEX>__:expired"
.
Avec cela, chaque fois qu'une clé expirera, vous obtiendrez un message publié sur votre connexion redis.
En ce qui concerne votre question, vous créez essentiellement une clé "normale" temporaire en utilisant set
avec un délai d'expiration en s/ms. Il doit correspondre au nom de la clé que vous souhaitez supprimer dans votre jeu.
Comme votre clé temporaire sera publiée sur votre connexion redis contenant le "__keyevent@0__:expired"
à son expiration, vous pouvez facilement supprimer votre clé de votre jeu d'origine car le message porte 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)