(Feature request)
SRANDMEMBER myset [count] [seed]
SRANDMEMBER myset // return one random member SRANDMEMBER myset 2 // return two random members SRANDMEMBER myset 1 "723432" // return one random member, randomness based on seed // first attribute could be switched to seed if second attribute is string not int (count of members vs. "seed")
RANDOMKEY [seed]
RANDOMKEY // return one random key RANDOMKEY "723432" // return one random key, randomness based on seed
The problem hit me today as I want to have a random set member but I want to have the same random set member based on a seed. In my example, the randomness should stay the same per IP.
Comment From: nicpottier
+1 on this, as it would also solve the rather hairy problem of using SRANDMEMBER in Lua scripts.
I'm not seeing any good way of implementing what I imagine is not a completely unusual pattern of having two level queues.
Essentially, my set up is this. Say I have a set of tasks that customers can trigger to take place. I want to process these as quickly as possible, but I don't want a single customer to 'hog' all available resources, even if they started first.
One nice way to do this in Redis is as follows:
Have a set 'queues' that contains the names of all the active queues, each customer having one queue keyed off their customer id.
For each customer, have a sorted set of tasks.
To add a new job, first push into the sorted set for that customer, say 'jobs:1234', then add that queue name to our 'queues' set. (so sadd queues jobs:1234)
To work through the jobs 'fairly' you simply do: 1) srandmember on the queues to get what queue to pop off of 2) do a 'zpop' in lua 3) if your zpop fails, then remove the queue from the 'queues' set
Ideally 1-3 are done in Lua to prevent any races, it should all be quick enough. Right now I can do 2 and 3 together in Lua and that works great:
local val = redis.call('zrange', ARGV[2], 0, 0)"
if next(val) == nil then
redis.call('srem', ARGV[1], ARGV[2])
return nil
else
redis.call('zremrangebyrank', ARGV[2], 0, 0)
return val[1]
end
The problem is that right now 1 has to take place separately, introducing the possibility of a race. Sure you can recover and try again, but if these queues are typically empty and there is high concurrency then that might happen a lot.
Having a way to 'seed' the srandmember would fix this, as our Lua script would then be 'pure'. Sadly, I'm not seeing any clear way to simulate a srandmember in Lua either, so I'm kind of stuck with a suboptimal solution.
Hope that makes some kind of sense!
Comment From: PATAPOsha
+1