Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching sortable/filterable data in Redis

I have a variety of data that I've got cached in a standard Redis hashmap, and I've run into a situation where I need to respond to client requests for ordering and filtering. Order rankings for name, average rating, and number of reviews can change regularly (multiple times a minute, possibly). Can anyone advise me on a proper strategy for attacking this problem? Consider the following example to help understand what I'm looking for:

  1. Client makes an API request to /api/v1/cookbooks?orderBy=name&limit=20&offset=0
  2. I should respond with the first 20 entries, ordered by name

Strategies I've considered thus far:

  • for each type of hashmap store (cookbooks, recipes, etc), creating a sorted set for each ordering scheme (alphabetical, average rating, etc) from a Postgres ORDER BY; then pulling out ZRANGE slices based on limit and offset
  • storing ordering data directly into the JSON string data for each key.
  • hitting postgres with an SELECT id FROM table ORDER BY _, and using the ids to pull directly from the hashmap store

Any additional thoughts or advice on how to best address this issue? Thanks in advance.

like image 411
patrickn Avatar asked May 19 '13 18:05

patrickn


1 Answers

So, as mentioned in a comment below Sorted Sets are a great way to implement sorting and filtering functionality in cache. Take the following example as an idea of how one might solve the issue of needing to order objects in a hash:

  1. Given a hash called "movies" with the scheme of bucket:objectId -> object, which is a JSON string representation (read about "bucketing" your hashes for performance here.

  2. Create a sorted set called "movieRatings", where each member is an objectId from your "movies" hash, and its score is an average of all rating values (computed by the database). Just use a numerical representation of whatever you're trying to sort, and Redis gives you a lot of flexibility on how you can extract the slices you need.

  3. This simple scheme has a lot of flexibility in what can be achieved - you simply ask your sorted set for a set of keys that fit your requirements, and look up those keys with HMGET from your "movies" hash. Two swift Redis calls, problem solved.

  4. Rinse and repeat for whatever type of ordering you need, such as "number of reviews", "alphabetically", "actor count", etc. Filtering can also be done in this manner, but normal sets are probably quite sufficient for that purpose.

like image 117
patrickn Avatar answered Oct 01 '22 13:10

patrickn