Redis
 sql >> Base de données >  >> NoSQL >> Redis

Redis Update Sorted Set à l'expiration de la clé

Vous avez raison, vous ne pouvez pas "mettre une date d'expiration" sur la valeur de l'ensemble trié elle-même.

Mais vous pouvez travailler avec la clé principale et capturer l'événement lorsque l'expiration se produit. Vous avez au moins 2 façons d'y parvenir :

  • Utilisation de la notification d'espace clé
  • Utiliser Redis Gears

Notification d'espace clé

À l'aide de Key Space Notification, vous pouvez capturer l'événement EXPIRE qui enverra un message PUBLISH que vous pourrez ensuite consommer.

Laissez-moi vous expliquer le flux de base :

Configurer les notifications

CONFIG SET notify-keyspace-events Ex
  • E :événements se produisant sur les clés
  • x  :capturer les événements expirés

Maintenant, votre base de données publiera un événement sur le __key*__:* chaîne.

Vous pouvez donc créer un service qui écoute ces événements mettre à jour l'ensemble (directement ou indirectement) :

psubscribe __key*__:*

Si vous avez une application qui définit la valeur et l'expiration suivantes

set foo bar EX 5

Vous devriez recevoir le message suivant

1) "pmessage"
2) "__key*__:*"
3) "[email protected]__:expired"
4) "foo"

Engins Redis

En utilisant Redis Gears, vous capturez le même événement (il est également basé sur la notification), mais il est plus facile d'écrire du code directement dans votre base de données Redis.

Vous pouvez créer un Gears comme suit :(il s'agit d'un script Python, j'utilise RedisInsight pour le déployer sur Redis)

def process(x):
    execute('LPUSH', 'expired:keys', x['value']['key']);

# Capture an expiration event and adds it to 'expired:events' stream
cap = GB('KeysReader')
cap.foreach(lambda x:
            execute('XADD', 'expired:events', '*', 'key', x['key']))
cap.register(prefix='*',
             mode='sync',
             eventTypes=['expired'],
             readValue=False)

# Consume new messages from expiration streams and process them somehow
proc = GB('StreamReader')
proc.foreach(process)
proc.register(prefix='expired:*',
              batch=100,
              duration=1, 
              trimStream = False)

Regardez la section commençant par cap = GB('KeysReader')

  • Cela écoutera toute expiration de clé prefix='*' &eventTypes=['expired']
  • En cas d'expiration, il ajoutera un message au 'expired:events' Redis Stream à l'aide de la commande XADD
  • Regardez ensuite la fonction proc = GB('StreamReader') qui traitera les flux
  • chaque fois qu'un nouveau message est dans le flux, il appellera le process() fonction.

Vous pouvez ajouter votre logique pour mettre à jour l'ensemble trié dans cette fonction. Dans mon exemple, je viens d'ajouter la clé expirée à une liste.

Permettez-moi de m'écarter un peu de votre question initiale.

Il semble que vous utilisiez Sorted Set pour créer une forme d'indexation pour vos données.

Si tel est le cas, vous devriez regarder RediSearch, un autre module Redis qui vous permet d'indexer Hash puis utilisez l'index pour effectuer des requêtes et des agrégations avancées.

Avec RediSearch, vous n'avez pas besoin d'ajouter de code pour gérer l'index, c'est fait automatiquement par la base de données, et vous pouvez interroger sur les champs.

Je vous invite à regarder :

  • Le module RediSearch
  • Démarrage de RediSearch

Désolé si ce n'est pas la raison pour laquelle vous utilisez Sorted Set, mais je pense que cela vaut la peine de vérifier car cela pourrait beaucoup simplifier votre code d'application si vous gérez l'index manuellement aujourd'hui.