Reading multiple Hashes from Redis in one call

I want to search for a key with highest value from multiple hashes in Redis. My keys are of this format -

emp:1, emp:2,...emp:n

Each having values in this format -

1. name ABC
2. salary 1234
3. age 23

I want to find an oldest employee from these Hashes. From what I have read about Redis there is no way to read multiple hashes in one call. Which means I need to iterate through all the emp keys and call HGETALL on each to get the desired result (I do have a set where all the emp ids are stored).

Is there a way I can minimize the number of hits to get this working?

Upvotes: 2

Views: 7838

Answers (2)

inquisitive
inquisitive

Reputation: 3639

tldr;

Yes you are right

... there is no way to read multiple hashes in one call ...

And so is @TheDude

... You could also create a Lua script to iterate over the Redis keys ...

Adding to it

It Appears that you are using Redis as a database. You have stored all your domain data and now you want to query it. This is misuse of Redis. It can be done but that is not what it was meant for. For this activity, if you use a real database it will be easier and more performant.

Redis is meant for caching frequently-used data[Note:1]. Note the two words (1) caching and (2) frequently-used. Caching is to store temporarily. If you want permanent storage - after server reboot - go for a database. Frequently-used says not to store All your data in there. Store only the subset that is actively being used. You can use Redis with all your data and even with permanent-store turned on, but then you have to tread very carefully.

For you purpose it seems using a generic database and SELECT MAX(age) FROM ... will be equally good if not better.

Or maybe,

You have quoted only part of the real problem and actually you are following the Redis best practices. In that cases I would suggest having a separate Sorted Set. For every employee inserted into the main keyset, also do ZADD employeeages 80 Alen where 80 is the age and Alen is presumable the ID of the person Alen.

To get the person ('s ID) with the maximum age, you can do

ZREVRANGEBYSCORE employeeages +inf -inf WITHSCORES LIMIT 0 1

If that looks bizarre then you are right - this is something very interesting! This will get your data not only in a single call, but in a single step in that call! Consider this: lets say you have a million employees (waao). Then this approach to get the oldest employee will be fastest, using a database and SELECT MAX(... will be runner up and your HGETALL or Lua script will be the slowest.

Use this approach if ages of your employees are frequently changing - like scores of players of an online game and you frequently want to query the topper or the looser - like updating the leaderboards. The downside of using this approach in place of a database is high redundancy. When (say) the address of an employee changes, you need to change a lot of records and to do that you need to make a lot of calls.


[1] As noted in comments, Redis is much more than just a cache for frequently-used data. I believe for this discussion, this definition is sufficient.

Upvotes: 1

TheDude
TheDude

Reputation: 3952

You can use a pipeline in Redis to run multiple commands and get their responses. That should allow you to execute multiple HGETALL commands. See the docs for more info. Not sure what library you are using for C#, but it should provide a way for you to use a pipeline.

You could also create a Lua script to iterate over the Redis keys and return the hash for the oldest employee.

Upvotes: 2

Related Questions