Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redis - get values of keys that match a regex

I need to save for each key, some values with different TTL.

e.g - for XXXX, values - val1(expiry time: 10),val2(expiry time: 20)

Option 1: My best practice could be: Use hash/sets with per-member expiry.

Unfortunately, Redis's containers ( lists, hashes, sets and sorted sets) do not support per-member expiry, although this functionality has been requested many times in the past.

Option 2: So I had to do something like this:

SETEX XXXX:0 10 val1

SETEX XXXX:1 20 val2

Now, I want to get all the values, that still not expired, which their key starts with XXXX.

So I tried this:

127.0.0.1:6379> keys XXXX:*
1) "XXXX:0"
2) "XXXX:1"

But I want to get the values, not the keys!

Option 3: How can I do it rather than putting the value into the key:

SETEX XXXX:val1 10 val1
SETEX XXXX:val2 20 val2

127.0.0.1:6379> keys XXXX:*
1) "XXXX:val1"
2) "XXXX:val2"

It would be my last option.. I will have to take the string after the :...

any idea how to implement option 1(alternative), or at least option 2, using a better way?

like image 962
user2503775 Avatar asked Jul 20 '14 14:07

user2503775


2 Answers

To achive this using one command you probably need to handle the expiring of the keys yourself.

Assuming that XXXX is a list of elements, an example if this would be to save the keys in an sorted set with an expire-at timestamp when as a score of the member.

ZADD XXXX [current-timestamp + 10] val1
ZADD XXXX [current-timestamp + 20] val2

And fetching them like this:

ZREVRANGEBYSCORE XXXX +inf [current-timestamp]

However you would want to remove the expired elements periodically:

ZREMRANGEBYSCORE XXXX -inf [current-timestamp]
like image 180
Jahaja Avatar answered Nov 08 '22 16:11

Jahaja


Option 1 isn't an option, as you had noted yourself.

Option 3 is quite wasteful - you'll be saving each value twice, once as the value and once in the key's name.

That leaves option 2, which is your best bet, although I recommend using SCAN instead of KEYS due to performance considerations. For each key name, simply do a GET to obtain the its value.

Alternatively (i.e. option 4) you could construct a list/set with your key names and use the SORT...GET to retrieve just the values. This will let you get only the values, but personally I think this approach is more complex to implement (you'll want to remove expired keys from your list/set periodically as well as construct it a priori) compared to #2.

like image 27
Itamar Haber Avatar answered Nov 08 '22 18:11

Itamar Haber