web-dev-qa-db-fra.com

TTL pour un membre défini

Est-il possible dans Redis de définir TTL (durée de vie) non pas pour une clé spécifique, mais pour un membre pour un ensemble?

J'utilise une structure pour les balises proposée par la documentation Redis - les données sont de simples paires clé-valeur, et les balises sont des ensembles contenant des clés correspondant à chaque balise, par ex.

> SETEX id:id_1 100 'Lorem ipsum'
OK
> SADD tag:tag_1 id:id_1
(integer) 1

La clé id:id_1 expirera comme prévu mais je ne vois pas de moyen efficace de supprimer le membre correspondant du tag:tag_1 ensemble.

Une façon dont je suis arrivé est d'utiliser un travail cron contenant un script qui supprimerait périodiquement les clés expirées des ensembles - en ajoutant tous les noms de balises à un autre ensemble, puis en parcourant toutes les balises, puis tous les identifiants correspondant à chaque balise et en vérifiant si la clé correspondante existe - sinon, appeler SREM.

Je ne pense pas que ce sera un moyen efficace et je voudrais peut-être garder les balises aussi propres que possible, car la taille des ensembles affectera probablement les performances de recherche par plusieurs balises (SINTER). Existe-t-il une voie plus "interne"?

54
Przemek

Il n'est pas possible d'expirer directement des éléments dans une liste, des ensembles ou des zsets.

Vous devez implémenter un mécanisme pour être averti lorsque l'élément maître expire, afin que vous puissiez gérer les ensembles correspondants en conséquence.

Voir la réponse à cette question, je pense qu'elle s'applique à votre cas d'utilisation (remplacez session par id, et utilisateur par tag):

Redis, expiration de session et recherche inversée

28
Didier Spezia

Non, ce n'est pas possible (et non prévu non plus ). L'approche recommandée consiste à utiliser un ensemble ordonné avec un score défini sur l'horodatage, puis à supprimer manuellement les clés expirées. Pour rechercher des clés non expirées, vous pouvez utiliser ZRANGEBYSCORE $now +inf, pour supprimer les clés expirées, ZREMRANGEBYSCORE -inf $now fera l'affaire.

Dans mon application, j'émets simplement les deux commandes chaque fois que j'interroge l'ensemble. Je combine également cela avec un temps d'expiration (long) sur l'ensemble lui-même pour éventuellement purger les ensembles inutilisés.

Cet article le parcourt plus en détail.

42
Václav Slavík

Vous ne pouvez pas expirer directement les éléments d'une liste, mais il est possible d'enregistrer un script lua sur votre serveur redis et d'ajouter cette fonctionnalité à redis. Redis Expiration basé sur la valeur

0
Milad