I have been thinking about taking a deep dive into NoSQL databases for a long time but wasn't sure which one should I start with. There are a lot of NoSQL databases in the market, each solving a set of problems. I wanted to learn a NoSQL database that does not have a steep learning curve and is generic enough to solve more than one problem. So, I started looking into different NoSQL databases when I found my starting point: Redis.
Redis is an in-memory key value datastore written in ANSI C programming language by Salvatore Sanfilippo. Redis not only supports string datatype but it also supports list, set, sorted sets, hashes datatypes, and provides a rich set of operations to work with these types. If you have worked with Memcached (an in-memory object caching system) you will find that it is very similar, but Redis is Memcached++. Redis not only supports rich datatypes, it also supports data replication and can save data on disk. The key advantages of Redis are :
- Exceptionally Fast : Redis is very fast and can perform about 110000 SETs per second, about 81000 GETs per second. You can use the redis-benchmark utility for doing the same on your machine.
- Supports Rich data types : Redis natively supports most of the datatypes that most developers already know like list, set, sorted set, hashes. This makes it very easy to solve a variety of problems because we know which problem can be handled better by which data type.
- Operations are atomic : All the Redis operations are atomic, which ensures that if two clients concurrently access Redis server will get the updated value.
- MultiUtility Tool : Redis is a multi utility tool and can be used in a number of usecases like caching, messaging-queues (Redis natively supports Publish/ Subscribe ), any short lived data in your application like web application sessions, web page hit counts, etc. There are a lot of people using Redis and they can be found at http://redis.io/topics/whos-using-redis
Getting Started with Redis
It is very easy to get started with Redis. On Unix boxes:
- You can either clone the git repository or download and unpack the tar.
- Open a new terminal and go to the directory in which you cloned or unpacked Redis and fire make command.
- Run ./src/redis-server which will start the Redis server with default configuration.
- Open a new terminal and type ./src/redis-cli which will start the Redis client you will use to work with Redis server.
For Windows user
- Download Redis from dmajkic git repository.
- Extract the zip and add <path to redis>\redis-2.1.8\64bit to your path.
- Open a new command shell and type redis-server
- Open a new command shell and type redis-cli
I am a Windows user so I am writing this article based on the latest redis distribution from dmajkic git repository. Once you have both the server and client running you can run some commands as shown in image below
redis> pingPONGredis> inforedis_version:2.1.8redis_git_sha1:00000000redis_git_dirty:0arch_bits:64....
If you are able to successfully run all the command then that means your Redis installation is complete. If you don't want to download and install Redis on your machine you can try Redis from the browser http://try.redis-db.com/
Let's take a look at its Data Types
The datatypes supported by Redis are Strings, Lists, Sets, Sorted Sets, Hashes. I will now briefly talk about different Redis types and play with them using redis-cli.
String is the basic data type supported by Redis. You can set the string value of a key, and you can get the string value of a key using SET and GET commands.
redis> set firstname shekharOKredis> set lastname gulatiOKredis> get firstname"shekhar"redis> get lastname"gulati"
There are a lot of other operations like APPEND, GETRANGE, MSET, STRLENGTH, etc. available for Strings. You can find the whole list here. If the values for your keys are integers, then you can use DECR, DECRBY, INCRBY, or INCR, which allow you to increment and decrement values. These can be very useful in scenarios where you want to maintain a count of something like number of hits for a web page.
redis> incr hitcounter(integer) 1redis> incr hitcounter(integer) 2redis> incr hitcounter(integer) 3redis> decr hitcounter(integer) 2
List is an ordered collection which lets you add any number of elements in it. The element can be unique or non-unique. Apart from adding and getting elements from a list, Redis supports lots of operations for lists like pop, push, range, etc. You can find the full list of commands here. Lets take an example that we want to maintain a list of words (uniqueness does not matter) and we want to get last 3 words we added in our system.
redis> LPUSH words austerity(integer) 1redis> LPUSH words socialism(integer) 2redis> LPUSH words moritorium(integer) 3redis> LPUSH words socialism(integer) 4redis> LPUSH words socialism(integer) 5redis> LRANGE words 0 21) "socialism"2) "socialism"3) "moritorium"
One thing to note is that in Redis lists are zero based.
Sets are unordered collections of binary strings. To add an element to a set you use the SADD command and to get all the members of a set you use the SMEMBERS command. You can find the full list of SET commands here. Lets take an example that we want to maintain a collection of all unique words added in our system.
redis> SADD uniquewords austerity(integer) 1redis> SADD uniquewords pragmatic(integer) 1redis> SADD uniquewords moritorium(integer) 1redis> SADD uniquewords socialism(integer) 1redis> SADD uniquewords socialism(integer) 0
As you can see, because we were using SET we can't add the same word (socialism) twice.
Sorted Sets are sets that can be sorted based on a score. So each time you add a value to the set you provide a score which is used for sorting. For example, we want to sort our words on the basis of their length.
redis> ZADD wordswithlength 9 austerity(integer) 1redis> ZADD wordswithlength 7 furtive(integer) 1redis> ZADD wordswithlength 5 bigot(integer) 1redis> ZRANGE wordswithlength 0 -11) "bigot"2) "furtive"3) "austerity"
There are lot of other useful commands for sorted sets which can be found here.
Hashes allow you store key-value pair against a hash. This can be useful in scenarios where you want to save an object with several properties.
redis> HSET user:1 name shekhar(integer) 1redis> HSET user:1 lastname gulati(integer) 1redis> HGET user:1redis> HGET user:1 name"shekhar"redis> HGETALL user:11) "name"2) "shekhar"3) "lastname"4) "gulati"
Loose ends -- what's not been covered
Apart from providing all these datatypes, Redis also supports Transactions and Publish/Subscribe. I will talk about these features in a future post.
We will take a deeper look into these datatypes in my future posts on Redis, where we will build up a Dictionary application using Redis as a datastore. I will be using Spring data Redis support for interacting with Redis. Spring support for Redis was also one of the reasons that I thought of using Redis.