I am trying to evaluate multiple options for caching technology. I finally decided to use Redis / Elasticache with Redis. After understanding the Redis Persistence, Replication Mechanism, Sharding/Cluster, Commands and Memory Management with Redis, I finally decided to design my Caching Engine with Redis.
But right at the beginning I am stuck with a critical design issue
My application deals with Forest type Data structures (i.e. Tree of Trees). To enhance my caching. I had decided to design 3 Caches'
In simple terms elements of 3rd cache (nodes) must point to elements of 2nd cache (Tree) which must points to elements of First Cache (Forest).
But the problem is Redis does not maintain references to the objects just the way Java does. In other words If I had created the same Cache in Java or Spring then My first cache would have held the Forest and Second cache would have only maintained a pointer to the current tree in the first cache and the third cache would have maintained a pointers to the nodes in the tree pointed by the second cache.
In such a way of using references I would have saved a lot of memory because I am just loading one instance of the forest in first cache and other cache elements are merely holding pointers/references to the first cache.
If the same thing is done in redis every keystore will actually store the complete instance of the object which means First cache would have complete forest stored and the second cache will hold different instance of the current tree and thirst will hold the current instance of the tree node.
Consider a Forest with Size 10 GB and each tree with size 500 MB and Current node with average size 50 MB then for one user traversing the tree redis will maintain 10 GB + 500 MB + 50 MB = 100550 MB average memory at any moment. Consider i have 100 current users logged and using the same forest then my memory usage will be 10 GB + (500 MB x 10) + (50 MB x 10) = 150500 MB
But if I use Java based caching engine then my utilization will always be 10GB only no matter how many users because once the forest is loaded then other caches will just hold the object references which consume negligible space.
Any thoughts on this. Can redis be used such that we can store reference to already stored object rather than creating new instances ?
At the very basic level, Redis stores scalar values, so no, it's not going to work quite like how you are imagining. However, you can fake it with a combination of sets and hashes (or strings). Let's say you store each individual tree item as a hash (or JSON string, whichever works better for your case), using cache keys like 12345|TREE (where 12345 is the ID of the tree). Then you have a set where you store all the tree IDs.
sadd TREES 12345 12346 12347 (etc)
hset 12345|TREE node1 node1value
hset 12345|TREE node2 node2value
Similarly, make a set for users and individual items for the current tree, and do the same for the individual nodes.
sadd USERS mgandhi froosevelt nmandela
set mgandhi|TREEID 12345
set froosevelt|TREEID 12346
set mgandhi|NODEID 1
set froosevelt|NODEID 2
Then you can use the SORT command to find out the location of each user: https://redis.io/commands/sort (even if you don't need the results to be sorted):
sort TREES by nosort get *|TREEID get *|NODEID
Hopefully that will be useful for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With