Wednesday, June 26, 2013

Redis 101

Redis (REmote DIctionary Service) is an open-source networked in-memory key-value data store. First released in 2009, currently sponsored by VMware, and since then it have been ranked the most popular key-value store by DB-Engine. Redis creator Salvatore Sanfilippo refers to his project as a “data structure server” to capture its unique handling of complex data types and other features. Interested ? Enough talking, let’s get down to business.

Download Redis installer from here.

Installation is straight forward:

Setup - Redis_2013-06-27_11-42-13

Setup - Redis_2013-06-27_11-42-21

Setup - Redis_2013-06-27_11-42-25

Setup - Redis_2013-06-27_11-42-29

Setup - Redis_2013-06-27_11-42-32

Setup - Redis_2013-06-27_11-42-36

Setup - Redis_2013-06-27_11-45-05

Start the Server go to Control Panel >> Administrative Tools >> Services , right click Redis Server and select Start.

Services_2013-06-27_11-49-50

Start the Client look for Redis Client (with red cube icon) in your start menu and open it. As you see it listens to port 6379 by default. You could ping your server by writing PING, if everything is good you will get PONG in return.

Redis Client_2013-06-27_11-56-46

GET & SET

As we said before, Redis is a key-value store. We store value inside a key and retrieve it later using that key. We can use the command SET to store the value "fido" at key "server:name" (server replies with Ok if everything is good) (Note that we used colons [:] within our key. This is a valid character that often logically separates a key into segments. It’s merely a matter of convention, with no deeper meaning in Redis.)

 SET server:name "fido"
To retrieve our value, we use GET command (server replies with “fido”)
 GET server:name 
You could also delete a given key and its associated value using DEL command and you can check for key existence using EXISTS (1 exists, 0 otherwise). We get and set multiple values in one command using MSET & MGET
 MSET 1 valueA 2 valueB
 MGET 1 2

Although Redis stores strings, it recognizes integers and provides some simple operations for them. If we want to keep a running total of something, we can create a count and then increment it with the INCR command (gives error for noninteger values).

 SET count 2
 INCR count
 GET count
Redis Client_2013-06-27_13-01-40

You can also increment by any integer (INCRBY) or decrement (DECR, DECRBY).


Redis Client_2013-06-27_13-04-08


It is good to know that these simple operations are atomic in Radis.


Expire


You can tell Radis to hold a key only for a certain period of time (in seconds) using EXPIRE command. You can test how long a key will exist for with the TTL command. It returns the number of seconds until it will be deleted (-1 means the key will never expire). All keys are permanent by default.


Redis Client_2013-06-27_13-40-01 


Setting and expiring keys is so common that Redis provides a shortcut command called SETEX. Also at any moment before the key expires, you can remove the timeout by running PERSIST KeyName.


A common trick for keeping only recently used keys is to update the expire time whenever you retrieve a value. This will ensure that your most recently used keys will remain in Redis, while the least recently used keys will just expire as normal.


Transactions


Redis like most DBMSs supports transactions. We begin the transaction with the MULTI command and execute it with EXEC command. So, wrapping two operations like SET and INCR in a single block will complete either successfully or not at all.


Redis Client_2013-06-27_13-17-56


As you may guess from the server response inside the transaction, commands are not executed instantly. Instead, they are queued and then executed in sequence.


Similar to ROLLBACK in SQL, you can stop a transaction with the DISCARD command, which will clear the transaction queue. Unlike ROLLBACK, it won’t revert the database; it will simply not run the transaction at all. The effect is identical, although the underlying concept is a different mechanism (transaction rollback vs. operation cancellation).


Complex Data Types


Radis can store lists, hashes, sets, and sorted sets natively. These collection data types can contain a huge number of values (up to 2^32 elements or more than 4 billion) per key. That’s more than enough for all Facebook accounts to live as a list under a single key.


List


A list is a series of ordered values that can act both as queues (first value in, first value out) and as stacks (last value in, first value out). Some of the important commands for interacting with lists are RPUSH, LPUSH, LLEN, LRANGE, LPOP, and RPOP. You can immediately begin working with a key as a list, as long as it doesn't already exist as a different type.



  • RPUSH puts the new value at the end (right) of the list.

  • LPUSH puts the new value at the start (left) of the list.

Redis 101 - Windows Live Writer_2013-06-27_14-42-33



  • LRANGE gives a subset of the list. It takes the index of the first element you want to retrieve as its first parameter and the index of the last element you want to retrieve as its second parameter. A value of -1 for the second parameter means to retrieve all elements in the list.

Redis Client_2013-06-27_14-46-47



  • LLEN returns the current length of the list.

  • LPOP removes the first (left) element from the list and returns it.

  • RPOP removes the last (right) element from the list and returns it.


    • Use LPUSH/RPOP to make List act like a queue.

    • Use LPUSH/LPOP to make List act like a stack.

  • LREM removes (some or all) matching elements from the list. It also requires a number to know how many matches to remove. Setting the count to 0 as we do here just removes them all. Setting the count greater than 0 will remove only that number of matches, and setting the count to a negative number will remove that number of
    matches but scan the list from the end (right side).

Redis Client_2013-06-27_14-53-25



  • RPOPLPUSH a single command for popping values from the tail of one
    list (right pop) and pushing to the head of another (left push). Surprisingly, there is no commands for RPOPRPUSH, LPOPLPUSH, or LPOPRPUSH.

Blocking Lists


It really interesting to know that Redis provides message queuing APIs natively. So, assume you want to write a simple messaging system where multiple clients can push data to one side of the queue and one or more listeners pop data from the other side of the queue. Listeners should just listen for new data and pop them as they arrive.



  • BRPOP the blocking version of RPOP, it blocks the connection when there are no elements to pop from any of the given lists.

Redis Client_2013-06-28_11-04-25


now open another Redis client window and push a message into messages list


Redis Client_2013-06-28_11-04-53


if you switched back to the blocking BRPOP command window, you will find it return the key, the popped value, and the time spent blocking


Redis Client_2013-06-28_11-05-11



  • BLPOP the blocking version of left pop LPOP

  • BRPOPLPUSH the blocking version of right pop left push BRPOPLPUSH

Set


Sets are unordered collections with no duplicate values and are an excellent choice for performing complex operations between two or more key values, such as unions or intersections.



  • SADD adds the given value to the set (duplication is not allowed).

  • SREM removes the given value from the set.

Redis Client_2013-06-27_16-41-05



  • SISMEMBER tests if the given value is in the set.

  • SMEMBERS returns a list of all the members of this set.

  • SUNION combines two or more sets and returns the list of all elements.

  • SINTER returns the intersection of two or more lists.

  • SDIFF returns the elements that exist in the first list only but not in the second list.

Redis 101 - Windows Live Writer_2013-06-27_17-00-54



  • SUNIONSTORE / SIMTERUNION / SDIFF stores the result of operation done on the second and third parameters into the first parameter.

Redis Client_2013-06-27_17-09-00



  • SMOVE moves one element from one set to another.

  • SCARD counts the set elements (set cardinality).

Redis Client_2013-06-27_17-21-00



  • SPOP returns a random element from a set and removes it.

  • SRANDMEMBER returns a random element from a set but does not remove it

Sorted Sets


Sorted set is similar to a regular set, but now each value has an associated score. This score is used to sort the elements in the set. Sorted sets take something from each of the other collections data types. They are ordered like lists and are unique like sets. They have field-value pairs like hashes, but rather than string fields, they are instead numeric scores that denote the order of the values. Internally, sorted sets keep values in order, so inserts can take log(N) time to insert (where N is the size of the set), rather than the constant time complexity of hashes or lists.



  • ZADD add a value with a specified score.

  • ZRANGE returns the elements between start index (zero-based) and end index (-1 means to the end of the sorted set. Put WITHSCORES at the end of command to get elements and scores, not only the elements. To get them in reverse, insert the word REV, as in ZREVRANGE.

Redis Client_2013-06-28_08-51-02



  • ZRANGEBYSCORE since we are using a sorted set, it’s more likely to get elements by score ranges instead of index ranges (x <= score <= y). We can make a score number exclusive by prefixing it with an opening parenthesis ( x < score <= y).

Redis Client_2013-06-28_11-49-34



  • -inf / inf negative / positive infinities. can be used in retrieval (by index or by score). We can also range by both positive and negative values.

  • ZREMRANGEBYRANK / ZREMRANGEBYSCORE remove values by rank or score.

  • ZINCRBY Increments the score of member in the sorted set stored at key by increment. If member does not exist in the sorted set, it is added with increment as its score (as if its previous score was 0.0). If key does not exist, a new sorted set with the specified member as its sole member is created. It is possible to provide a negative value to decrement the score.

Redis Client_2013-06-28_08-58-48



  • ZUNIONSTORE Computes the union of numkeys sorted sets given by the specified keys, and stores the result in destination set. It is mandatory to provide the number of input keys (numkeys) before passing the input keys and the other (optional) arguments. Parameters needed:


    • destination ==> a set to hold the union operation result

    • numkeys ==> number of keys you are going to join.

    • weight ==> optional number(s) to multiply each score of the relative key by (if you have two keys, you can have two weights and son on)

    • aggregate ==> optional rule to specify how the results of the union are aggregated. This option defaults to SUM, where the score of an element is summed across the inputs where it exists. When this option is set to either MIN or MAX, the resulting set will contain the minimum or maximum score of an element across the inputs where it exists.

Redis 101 - Windows Live Writer_2013-06-28_12-29-14


In the above example we prepared two sorted sets, sset1 with elements (1 “one” 2 “two”) , sset2 with elements (1 “one” 2 “two” 3 “three”). Then tell Redis to merge these two sets with the following parameters:




    • store the operation result in sorted set named out

    • we going to merge 2 sorted sets, then provide them sset1 sset2.

    • we going to use WEIGHTS, then provide these weights 2 3.

Hash


Hash is a collections object that can hold any number of key-value pairs.



  • HMSET store the key-value pairs into the hash (first parameter.

  • HVALS returns the values of a hash.

  • HKEYS returns the keys of a hash.

  • HGET returns the value of of a single key in a hash.

Redis Client_2013-06-28_10-09-24



  • HDEL deletes a key-value pair from a hash.

  • HSET updates or adds a value at a specified key in a hash.

  • HINCRBY increments an integer field value by some count in a hash. It is possible to provide a negative value to decrement.

  • HLEN returns the number of fields in a hash.

Redis Client_2013-06-28_10-17-28





Database Namespaces


You may have been wondering, which database we working on. So far, we have interacted only with a single namespace. In Redis’s terminology, a namespace is called a database and is keyed by a number. So far, we’ve always interacted with the default namespace 0 (also known as database 0).


  • Use SELECT command to switch to different database and provide it a DB number. Setting a value to a key in one database will not affect any other key in other databases.

clip_image001



  • Since all databases are running in the same server instance, Redis lets us move keys from one database to another with the MOVE command.

clip_image002


This can be useful for running different applications against a single Redis server but still allow these multiple applications to trade data between each other.

More commands



  • RENAME rename a key

  • TYPE return the type of a key’s value

  • DEL deletes a key-value pair

  • FLUSHDB removes all keys in database

  • FLUSHALL removes all keys from all databases on this server instance.

Redis’s data types and the complex queries it can perform make it much more than a standard key-value store. It can act as a stack, queue, or priority queue; can be an object store (via hashes); and even can perform complex set operations such as unions, intersections, and subtractions (diff). It provides many atomic commands, and for those multistep commands, it provides a transaction mechanism. It has a built-in ability to expire keys, which is useful as a cache.




In this post we just introduced Redis as a data structure server. In later post we going to cover the advanced features of Redis.