How to "EXPIRE" the "HSET" child key in redis?
I need to expire all keys in redis hash, which are older than 1 month.
Solution 1:
This is not possible, for the sake of keeping Redis simple.
Quoth Antirez, creator of Redis:
Hi, it is not possible, either use a different top-level key for that specific field, or store along with the filed another field with an expire time, fetch both, and let the application understand if it is still valid or not based on current time.
Solution 2:
Redis does not support having TTL
on hashes other than the top key, which would expire the whole hash. If you are using a sharded cluster, there is another approach you could use. This approach could not be useful in all scenarios and the performance characteristics might differ from the expected ones. Still worth mentioning:
When having a hash, the structure basically looks like:
hash_top_key
- child_key_1 -> some_value
- child_key_2 -> some_value
...
- child_key_n -> some_value
Since we want to add TTL
to the child keys, we can move them to top keys. The main point is that the key now should be a combination of hash_top_key
and child key:
{hash_top_key}child_key_1 -> some_value
{hash_top_key}child_key_2 -> some_value
...
{hash_top_key}child_key_n -> some_value
We are using the {}
notation on purpose. This allows all those keys to fall in the same hash slot
. You can read more about it here: https://redis.io/topics/cluster-tutorial
Now if we want to do the same operation of hashes, we could do:
HDEL hash_top_key child_key_1 => DEL {hash_top_key}child_key_1
HGET hash_top_key child_key_1 => GET {hash_top_key}child_key_1
HSET hash_top_key child_key_1 some_value => SET {hash_top_key}child_key_1 some_value [some_TTL]
HGETALL hash_top_key =>
keyslot = CLUSTER KEYSLOT {hash_top_key}
keys = CLUSTER GETKEYSINSLOT keyslot n
MGET keys
The interesting one here is HGETALL
. First we get the hash slot
for all our children keys. Then we get the keys for that particular hash slot
and finally we retrieve the values. We need to be careful here since there could be more than n
keys for that hash slot
and also there could be keys that we are not interested in but they have the same hash slot
. We could actually write a Lua
script to do those steps in the server by executing an EVAL
or EVALSHA
command. Again, you need to take into consideration the performance of this approach for your particular scenario.
Some more references:
- https://redis.io/commands/cluster-keyslot
- https://redis.io/commands/cluster-getkeysinslot
- https://redis.io/commands/eval