Redis - What is Redis? And do i need it?

Redis ... just another fucking noSQL database or serious competitor for memcache and all the other key/value stores out there?

Posted by Fichtl on 24.07.2012

What is it?

Using Redis is like using memcached but it has some cool additional features ... the best one:

It's filesystem-backed if you wish! So Redis is not just good for a caching layer ... it's a database. There are two methods of persistence: RDB is snapshoting from time to time ... or AOF a append-only journal file thats written in a background task. And you can combine both methods. 

Redis has an easy-to-use replication-mode (like memcached) and some cool datatypes which i will describe below. 

Installing is not so hard, out there are many good tutorials. You can  install via apt and dotdeb-repository or just download the tar-file and  run a make command. See the following links: 

  • http://redis.io/topics/quickstart
  • http://vvv.tobiassjosten.net/linux/installing-redis-on-ubuntu-with-apt
  • http://library.linode.com/databases/redis/debian-5-lenny

I want to use it with PHP and there are some client-classes  for it and many other programming languages, check the Redis clients-page. Here is one example for Predis and below you see how you use it with PHPRedis

"Hello World" for Predis

 

require __DIR__.'/lib/Predis/Autoloader.php'; PredisAutoloader::register(); $config = array( 'host' => '127.0.0.1', 'port' => 6379, 'database' => 15 ); $client = new PredisClient($config); $client->set('hello', 'world'); $retval = $client->get('hello'); var_dump($retval);

"Hello World" for PHPRedis

PHPRedis seems to be much faster (it's a PHP-extension in C) ... see Benchmarks below. Install-tutorial for PHPRedis. 

$redis = new Redis() or die("Can'f load redis module."); $redis->connect('127.0.0.1'); $redis->set('hello', 'world'); $retval = $redis->get('hello'); var_dump($retval);

Lists

Lists of strings are sorted by insertion order, it's possible to push items to the front (lpush) or the tail (rpush) of a list. A list can have 4 billion elements. Of course you can remove items form lists, get the size of a list and fetch a range of elemets by index. Inserting at a specific index is also possible.

$redis->lPush('mylist', 'item1'); $redis->rPush('mylist', 'item2'); $redis->rPush('mylist', 'item3'); $redis->lPush('mylist', 'item0'); $size = $redis->lSize('mylist'); var_dump($size); var_dump($redis->type('mylist')); var_dump($redis->lGet('mylist', 0)); var_dump($redis->lGetRange('mylist', 0, $size-1)); $redis->delete('mylist');

Sets

Sets can hold an unordered collection of strings. Each string can only be once in the set. You can add, remove and check set-members in a constant time regardless of the number of elements. Another datatype are sorted sets where every item has an numeric sorting-key (score).

$redis->sAdd('myset', 'item1'); $redis->sAdd('myset', 'item2'); $redis->sAdd('myset', 'item3'); var_dump($redis->sContains('myset', 'item1')); // true var_dump($redis->sContains('myset', 'item4')); // false var_dump($redis->sSize('myset')); var_dump($redis->sMembers('myset')); $redis->sAdd('myset2', 'item2'); $redis->sAdd('myset2', 'item3'); $redis->sAdd('myset2', 'item4'); var_dump($redis->sDiff('myset','myset2')); var_dump($redis->sUnion('myset','myset2')); var_dump($redis->sInter('myset','myset2'));

Hashmaps

Hashmaps (aka Hashes) are perfect for storing objects like "user" or "article" or whatever. It's a key/value map stored under a distinct id. For example a user with the key user-1 can have a key/value map with {name:'derfichtl', 'email':'test@test.at'} ... here some examples for working with hashes:

// setting $redis->hSet('user-derfichtl', 'username', 'derfichtl'); $redis->hSet('user-derfichtl', 'email', 'derfichtl[AT]gmail.com'); $redis->hSet('user-derfichtl', 'name', 'Michael Feichtinger'); // or so: $redis->hMset('user-derfichtl', array('username'=>'derfichtl', 'email'=>'derfichtl[AT]gmail.com', 'name'=>'Michael Feichtinger')); // reading foreach($redis->hKeys('user-derfichtl') as $key) { var_dump($key.': '.$redis->hGet('user-derfichtl', $key)); } // or so: var_dump($redis->hVals('user-derfichtl')); var_dump($redis->hGetAll('user-derfichtl')); if($redis->hExists('user-derfichtl', 'name')) { var_dump($redis->hGet('user-derfichtl', 'name')); }

A Little Performance Test

On an Amazon EC2 micro instance (Ubuntu) ...

// set/insert

for($i=0;$i<1000;$i++) { // set // get }

  • MEMCACHED: 0.10s
  • PREDIS (AOF onesecond): 0.20s
  • PHPREDIS (AOF onesecond): 0.12s
  • PHPREDIS (NO file-persistence): 0.09s
  • MYSQL: 0.155s

// get

for($i=0;$i<10000;$i++) { // get }

  • MEMCACHED: 0.5s
  • PHPREDIS (AOF onesecond): 0.45s
  • MYSQL: 0.5s

Journal File looks like ...

It's a simple plain text file and looks so: 

*2 $6 SELECT $2 15 *3 $3 SET $5 hello $5 world *3 $3 SET $5 hello $5 world

Who is using it?

Flickr, Digg, StackOverflow, GitHub, ...

So, now you should know enough about Redis to talk about like a pro :)