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')