Finding non-expiring keys in Redis

Modified from a site that I can't find now.

redis-cli keys  "*" | while read LINE ; do TTL=`redis-cli ttl "$LINE"`; if [ $TTL -eq  -1 ]; then echo "$LINE"; fi; done;

edit: Note, this is a blocking call.


@Waynn Lue's answer runs but uses the Redis KEYS command which Redis warns about:

Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases.

Redis documentation recommends using SCAN.

redis-cli --scan | while read LINE ; do TTL=`redis-cli ttl "$LINE"`; if [ $TTL -eq  -1 ]; then echo "$LINE"; fi; done;

If you want to scan for a specific key pattern, use:

 redis-cli --scan --pattern "something*"

In case somebody is getting bad arguments or wrong number of arguments error, put double quotes around $LINE.

So,it would be

redis-cli keys  "*" | while read LINE ; do TTL=`redis-cli ttl "$LINE"`; if [ $TTL -eq  -1 ]; then echo "$LINE"; fi; done;

This happens when there are spaces in the key.


I needed to extract non-expiring keys from bigger (40GB) dataset, so using keys command was not suitable for me. So in case someone is looking for offline/non-blocking solution, you can use https://github.com/sripathikrishnan/redis-rdb-tools for extraction of non-expiring keys from redis rdb dump.

You can just install libraries via pip:

pip install rdbtools python-lzf

Then create simple parser which extracts keys and values which has expiration set to None:

from rdbtools import RdbParser, RdbCallback
from rdbtools.encodehelpers import bytes_to_unicode

class ParserCallback(RdbCallback):

    def __init__(self):
        super(ParserCallback, self).__init__(string_escape=None)

    def encode_key(self, key):
        return bytes_to_unicode(key, self._escape, skip_printable=True)

    def encode_value(self, val):
        return bytes_to_unicode(val, self._escape)

    def set(self, key, value, expiry, info):
        if expiry is None:
            print('%s = %s' % (self.encode_key(key), self.encode_value(value)))


callback = ParserCallback()
parser = RdbParser(callback)
parser.parse('/path/to/dump.rdb')