Search code examples
data-structuresredishashmap

Redis : Pros and Cons for following two approaches


I have a lot of javascript objects like:

var obj1 = {"key1" : value1, "key2" : value2, ...}
var obj2 = {"key3" : value3, "key4" : value4, ...}

and so on...

Following are the two approaches :

  1. Store each object as Redis Hash i.e. one-to-one mapping.
  2. Have one Redis Hash(bucketing can be done for better performance), store each object as stringified object in each key of hash i.e. for each object having a key value pair in the Redis Hash. Parse the object when we need to use the object.

1) -> Takes more space than 2) but has better performance than 2)

2) -> Takes less space than 1) but has worse performance than 1)

Is there a way to determine which approach would be better in the long run?

Update: This data is used on the client side (AngularJS), so all parsing of stringified JSON is done in the frontend.


Solution

  • This would probably be solved by deciding which method minimises the number of steps required to extract the required data from redis.

    Case 1: Lots of nested objects
    If your objects have a lot of nesting, ie objects within objects, like this,
    obj = {key1:{key2:value1, key:3{key4:value2}}}

    You should probably stringify and store them.
    Because Redis does not allow nesting of data structures. You can't store a hash within another hash. And storing the name of hash2 as a key within hash1 and querying hash2 after getting hash1 and so on is unnecessarily complex and has a lot of queries. In this case all you have to do is get the entire string from Redis and JSON.parse it. and you can get whatever data you want from the Object.

    Case 2: No nested objects.
    But on the other hand, if there is no nesting of objects and you store it as a string, you have to JSON.parse() every time you get the data from Redis. And parsing JSON is blocking and is CPU intensive. Node.js: does JSON.parse block the event loop?

    Redis documentation also says that hashes are encoded in a very small space, so you should try representing your data using hashes every time it is possible. http://redis.io/topics/memory-optimization

    So, in this case, you could probably go ahead and store them all as individual hashes as querying a particular value will be a lot easier.

    ---------Update---------
    Even if the JSON parsing is done on the client, try not to do an extra computation needlessly :)
    But nested objects are easier to store and query as a string. Otherwise, you'll have to query more than one hash table. In this case storing as stringified object might just be better for performance.

    Redis stores small hashes very efficiently. So much that storing multiple small hashmaps is more memory efficient than one big hashmap.
    the number of keys deciding about the encoding to use can be found in redis.conf
    hash-max-zipmap-entries 512
    also the value of each key should be hash-max-zipmap-value 64
    So, you can now decide on the basis of nesting of your objects, number of Hash Keys below which Redis is more memory efficient and the value assigned to your keys.

    Do go through http://redis.io/topics/memory-optimization