Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redis: How to delete all keys older than 3 months

Tags:

redis

I want to flush out all keys older than 3 months. These keys were not set with an expire date.

Or if that is not possible, can I then delete maybe the oldest 1000 keys?

like image 245
Christoffer Avatar asked May 13 '13 08:05

Christoffer


People also ask

How do I flush all Redis keys?

In Redis you can flush cache/database and delete all keys from all databases or from the particular database only using FLUSHALL and FLUSHDB commands. To delete all keys from all Redis databases, use the FLUSHALL command. To delete all keys of the selected Redis database only, use the FLUSHDB commnad.

How do I delete old data from Redis?

Redis Commands There are two major commands to delete the keys present in Redis: FLUSHDB and FLUSHALL. We can use the Redis CLI to execute these commands. The FLUSHDB command deletes the keys in a database. And the FLUSHALL command deletes all keys in all databases.

How do I delete multiple keys in Redis?

Redis does not offer a way to bulk delete keys. You can however use redis-cli and a little bit of command line magic to bulk delete keys without blocking redis. This command will delete all keys matching users:* If you are in redis 4.0 or above, you can use the unlink command instead to delete keys in the background.

Does Redis automatically delete expired keys?

After the timeout has expired, the key will automatically be deleted. A key with an associated timeout is often said to be volatile in Redis terminology. The timeout will only be cleared by commands that delete or overwrite the contents of the key, including DEL , SET , GETSET and all the *STORE commands.


4 Answers

Using the object idletime you can delete all keys that have not been used since three months. It is not exactly what you ask. If you created a key 6 months ago, but the key is accessed everyday, then idletime is updated and this script will not delete it. I hope the script can help:

#!/usr/bin/env python
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
for key in r.scan_iter("*"):
    idle = r.object("idletime", key)
    # idle time is in seconds. This is 90days
    if idle > 7776000:
        r.delete(key)
like image 109
Saverio Proto Avatar answered Oct 05 '22 03:10

Saverio Proto


Are you NOW using an expire? If so, you could loop through all keys if no TTL is set then add one.

Python example:

for key in redis.keys('*'):
    if redis.ttl(key) == -1:
        redis.expire(key, 60 * 60 * 24 * 7)
        # This would clear them out in a week

EDIT As @kouton pointed out use scan over keys in production, see a discussion on that at: SCAN vs KEYS performance in Redis

like image 43
Dave Albert Avatar answered Oct 05 '22 05:10

Dave Albert


A bit late, but check out the OBJECT command. There you will find object idle time (with 10 second resolution). It's used for debugging purposes but still, could be a nice workaround for your need.

References: http://redis.io/commands/object

like image 20
Gonzalo Avatar answered Oct 05 '22 05:10

Gonzalo


Sorry, that's not possible, as stated in the comments above. In Redis it's crucial to create your own indexes to support your access patterns.

Tip: What you should do is to create a sorted set (ZADD) with all new or modified keys, and set the score to a timestamp. This way you can with ease fetch the keys within a time period using ZRANGEBYSCORE.

If you want to expire your existing keys, get all keys (expensive) and set a TTL for each using the EXPIRE command.

like image 20
ptz0n Avatar answered Oct 05 '22 04:10

ptz0n