skip to Main Content

Working an learning some Redis and I am running into an issue that I can’t figure out why it is not working.

It is my understanding from some posts and documentation I read that I can store data with similar keys like this

redis.set("fruit:1", "apple")
# OK
redis.set("fruit:2", "banana")
# OK

and it is my understanding I should be able to get all fruit like this

redis.get("fruit:*")

But I am missing something because this keep returning null and I cannot figure out what I need to do to return something like

=> apple, banana

I was able to figure out, using scan (suggested in answer below as well) how to return all matching fruit keys, but what I need is to search for all matching fruit keys, and then return the values for them.

@redis.scan_each(match: "fruit:*") do |fruit|
  Rails.logger.debug('even run?')
  fruits << fruit
end

=> fruit:1, fruit:2 # What I need though is apple, banana

What solved it (at least so far) is using mGet

@redis.scan_each(match: "fruit:*") do |fruit|
  Rails.logger.debug('even run?')
  fruits << @redis.mGet(fruit)
end

2

Answers


  1. As far as I know, you can not do that (it would be cool to be possible).
    Instead you have to run a scan SCAN 0 MATCH "fruit:*" COUNT 500 where 500 is number of keys to parse in the first iteration. So you have to run multiple iterations… until you reach the end of your key count.

    If you want to get all keys with a single iteration, first you need to know how many keys there are in your DB, so you can run a command to find the total amount of keys:
    dbsize which you can use instead of the 500 value in my example.

    redis-cli dbsize

    or

    redis-cli INFO Keyspace | grep ^db0 | cut -f 1 -d "," | cut -f 2 -d"="

    To return all values from all keys you can use MGET

    https://redis.io/commands/mget

    Maybe you can also take a deeper look at data structures

    Maybe the solution above is not the correct one, in your case you can also use a set just to add your fruits in there.
    https://redis.io/commands/sadd

    Login or Signup to reply.
  2. SCAN can be a very expensive operation as it must traverse all the keys, even if you use a pattern. Because Redis is single-threaded, while that SCAN is happening, nothing else can happen and other requests are blocked. If you only have a few keys, this is fine. But if you have a lot of keys, this can cause serious performance issues.

    What you need is an index that contains the keys of all of your fruits. You could use a Set to do this and whenever you add a fruit, you add the key to the Set:

    > SET fruit:1 apple
    > SADD fruit:index 1
    

    Then, when you need all the fruits, you just get the members of the Set:

    > SMEMBERS fruit:index
    1) "1"
    2) "2"
    

    Then get the values of the fruits:

    > GET fruit:1
    > GET fruit:2
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search