Redis has a bunch of datatypes: Strings, Hashes, Lists, Sets and Sorted Sets. Firstly, you’ll note that there’s a lack of the integer data type, but redis has an INCR command. This command operates on redis’s string data type, and if that string is actually an integer, that integer will be atomically incremented. Whilst I know that you can store integers (and floats) in strings, it doesn’t seem to me to be a good way of storing these commonly used data types. Additionally if you’re using a redis binding and you do something like this:
>>> redis.set("my_key",0) True >>> redis.get("my_key") '0'
The binding has no way of figuring out if the data it gets back should be: an integer, or the string “0”. This means that any code one writes where integer values for keys are set, one has to add extra code when one pulls the data out of redis, so that the data can be treated as integer values. Alternative key/value stores and databases have had the ability to store values in integer data types for long time. (redis also does the same thing with strings for booleans and nulls)
You’d think that with redis’s more advanced data structures (hashes and lists for example), you’d be able to do some nesting, so that for example you could have a list of hashes. Unfortunately this is not the case. When we were working with redis we spent a little while trying to come up with a solution and we came up with two alternatives
A list of json strings: redis’s list structure can only store strings (or intish strings), so we nested our data structures using json strings. This meant that when we took items out of the list they had to be json parsed and json encoded. This wasn’t too much of a pain, but it wasn’t particularly elegant.
Make keys heirarchical: For student robotics we decided that we’d namespace our keys in the same way, prefixed with “org.srobo”. For our a list of teams we had keys of the form “org.srobo.teams.n.thing” where n was the team number. This meant that we could nest our data structures by using a tree of variables, storing things in some nodes and nothing in others.
Of these solutions I tend to prefer the first one. Whilst it’s slightly more horrible it does mean that all your data is conceptually stored in one place in redis. Redis makes no distinction between keys, so there’s nothing in redis that allows it to interact directly with our structured heirarchy, instead that was dealt with in python scripts.
Redis has a publish subscribe mechanism which is extremely useful. The basic idea being that you can subscribe to or publish on a “channel”. There isn’t anything that particularly relates the data you’ve got stored in redis to the way output occurs on any given channel, in fact you could not store any data in redis and just use it as a publish subscribe mechanism. I can think of many strategies for combining uses of variables and keys, but for our project we came up with a pretty good solution.
In our solution we use the redis command monitor which sends an update any redis command is executed, we then read the output of that and any time a variable is modified we publish a message on a channel with the same name as the variable letting any subscribed programs know that that variable has been updated. We don’t publish the value but just the fact that an update has occured.
Redis is a very cool piece of technology, and I think it’s definitely worth having a play around with. We used it for a production system over the weekend with about 20 updates a second and it seemed to work fairly stably. I’m not convinced I prefer the system over SQL or other key/value stores (like MongoDB), but I’ve met people who use it in production, and they all say that they love it.