Redis For Beginners

March 13, 2021

Nowadays you probably have heard of Redis. If you have never used it, it's good to know about it.

So what is Redis? It is an in-memory NoSQL database.

It is done in memory; because of this, Redis queries are much faster than SQL queries.

It is a database because it stores data (although by default it is not persistent).

It is a NoSQL database because it is not relational but instead uses key-value pairs.

So Redis is similar to a relational database in a sense that they are both databases. However, Redis is not an alternative to a relational database. You don't want to give up MySQL/PostgreSQL completely in exchange for Redis. They are different tools for different tasks. Use Redis for time-critical, non-persistent queries. Use MySQL/PostgreSQL for durability, SQL queries, and security.

Redis is NOT an alternative to DB. It's not like you have to give up MySQL/ PostgreSQL and switch to Redis. It's a different tool to do different tasks that MySQL is not good at. On the other hand, you use MySQL to do things that Redis isn't good at. Don't use Redis for durability, to make SQL queries, or security. Use PostgreSQL.

Using Redis For The First Time

Redis is available almost everywhere. To install Redis, check out the official download page here.

If you have a mac, you can install Redis via homebrew:

brew install redis

Once installed, to run the Redis server, run:

redis-server

I personally like to run it on the background. To do that, you can run:

redis-server --daemonize yes

Let's get the feel for it. You can either use your choice language's Redis library (they should have one) or access it directly with Redis CLI. In this case, I will use the latter. Run:

redis-cli

As mentioned earlier, Redis is a NoSQL database. At its core, it stores key-value pairs. To set a new key-value pair, use the SET command.

SET hello redis
# OK

That's it! You just set a key "hello" with a value "redis". To get that value, you can run the GET command:

GET hello
# "redis"

If you try to get a nonexistent key, Redis will not return anything

GET dontexist
# (nil)

To delete a key-value pair, use DEL:

DEL hello
# (integer) 1

GET hello
# (nil)

Notice that when you run DEL hello the first time, it returns (integer) 1. This is because Redis is returning the number of affected items. In this case, you only deleted a pair, so it returns 1.

To quit Redis cli, type the command EXIT or press Ctrl-C. To actually shut down the Redis server, from inside the cli, run SHUTDOWN.

Finally, if you want to remove all the keys, run the FLUSHALL command.

Redis Data Types

Earlier you saw how you can run a simple key-value pair from inside redis-cli with:

SET hello redis
# OK

GET hello
# "redis"

Redis actually has 5 different data types. What you just did above was setting a key-value pair for a string data type. The 5 data types are:

  1. String
  2. List
  3. Set
  4. Hash
  5. Zset

Let's go through the other 4.

List

Redis has a list data type. It is similar to Python's list or Javascript array. A list is a sequence of characters. Some commonly used commands are:

  • LSET to set the value of an item in the list from the left.
  • LRANGE to return the items in the list from the left to the right.
  • RPUSH to push a value to the right end of the list.
  • RPOP to remove and return the rightmost item.

Note that they are all prefixed with either L (left) or R (right). For each L command, there is a R counterpart and vice-versa.

Let's try them out. With redis-server running, open the CLI with the redis-cli command.

RPUSH hellolist hello1
# (integer) 1

RPUSH hellolist hello2
# (integer) 2

RPUSH hellolist hello3
# (integer) 3

LRANGE hellolist 0 -1
# 1) "hello1"
# 2) "hello2"
# 3) "hello3"

RPOP hellolist
# "hello3"

LRANGE hellolist 0 -1
# 1) "hello1"
# 2) "hello2"

LSET hellolist 1 helloNew
# OK

LRANGE hellolist 0 -1
# 1) "hello1"
# 2) "helloNew"
  • Note that each time you add to hellolist, Redis returns an increasing integer value (integer) 1, (integer) 2, etc. Redis returns the size of the hellolist list.
  • The command LRANGE hellolist 0 -1 is useful to display the entire list. 0 is the first index of the list and -1 is the last index of the list.
  • RPOP mutates the list by removing the right-most element on the list. It also returns the removed element.
  • LSET in this context mutates the nth index of the list. LSET hellolist 1 helloNew mutates the item in index 1 (2nd item of the list) to the new value "helloNew".

Set

Redis has a set data type. If you are familiar with Python, Redis' set is similar to Python's set. It is a collection of unique items. Some commonly used commands are:

  • SADD to add an item.
  • SMEMBERS to return the items.
  • SREM to remove an item.
  • SCARD to return the number of items.
  • SISMEMBER to check if an item is found.

Let's play around using redis-cli:

SADD helloset chocodonut
# (integer) 1

SADD helloset sugardonut
# (integer) 1

SADD helloset glazeddonut
# (integer) 1

SADD helloset sugardonut
# (integer) 0

SMEMBERS helloset
# 1) "chocodonut"
# 2) "glazeddonut"
# 3) "sugardonut"

SREM helloset sugardonut
# (integer) 1

SMEMBERS helloset
# 1) "chocodonut"
# 2) "glazeddonut"

SCARD helloset
# (integer) 2

SISMEMBER helloset chocodonut
# (integer) 1
  • To create a set, use SADD to add items into a new set.
  • To view a set, use SMEMBERS (much more concise syntax than LRANGE) and to view the number of elements inside the set, use SCARD.
  • To check whether an item exists in a set, use SISMEMBER. If it returns 1, it is true. If it returns 0, it is false.

Hash

Hash in Redis is similar to Python's dictionaries. They hold unique key-value pairs. Technically Redis itself is a collection of key-value pairs. So a hash data type is like a mini Redis. Some commonly used operations:

  • HSET to set a hash key-value pair.
  • HGET to get a value using a key.
  • HDEL to remove a key.
  • HLEN to return then umber of key-value pairs in that hash.
  • HGETALL to return all key-value pairs.

Let's try it out on the CLI:

HSET hellohash key1 value1
# (integer) 1

HSET hellohash key2 value2
# (integer) 1

HSET hellohash key3 value3
# (integer) 1

HGET hellohash key1
# "value1"

HGETALL hellohash
# 1) "key1"
# 2) "value1"
# 3) "key2"
# 4) "value2"
# 5) "key3"
# 6) "value3"

HLEN hellohash
# (integer) 3

HDEL hellohash key2
# (integer) 1

HGETALL hellohash
# 1) "key1"
# 2) "value1"
# 3) "key3"
# 4) "value3"

Zset

A zset (sorted-set) is a data type unique to Redis. It is similar to the set data type because it contains a collection of unique items. It is also similar to a hash because each item is assigned to a score (float numbers), just like a hash's key is assigned to a value. The big idea of zset is to make it easy to sort items based on their assigned scores (hence the name sorted-set). Some common commands:

  • ZADD to add a new item to a zset.
  • ZRANGE to display items positionally.
  • ZRANGEBYSCORE to display items based on their scores.
  • ZREM to remove an item.

It was harder for me to grasp zset because I haven't really seen anything like it, so the best way is to create one and see it yourself!

ZADD hellozset 500 first
# (integer) 1

ZADD hellozset 300 second
# (integer) 1

ZADD hellozset 400 third
# (integer) 1

ZRANGE hellozset 0 -1
# 1) "second"
# 2) "third"
# 3) "first"

ZRANGE hellozset 0 -1 WITHSCORES
# 1) "second"
# 2) "300"
# 3) "third"
# 4) "400"
# 5) "first"
# 6) "500"

ZRANGEBYSCORE hellozset 0 450
# 1) "second"
# 2) "third"

ZRANGEBYSCORE hellozset 0 450 WITHSCORES
# 1) "second"
# 2) "300"
# 3) "third"
# 4) "400"

ZREM hellozset second
# (integer) 1

ZRANGE hellozset 0 -1 WITHSCORES
# 1) "third"
# 2) "400"
# 3) "first"
# 4) "500"
  • There are three items in the zset: "first", "second", and "third". Each item is associated with the scores of 500, 300, and 400 respectively. The "first" item has a score of 500, the "second" item 300, and the "third" item 400.
  • You may notice that the command to display all items in a zset is similar to list: lrange hellolist 0 -1 vs zrange hellozset 0 -1. However, note that when you do that on a zset, the items are sorted by their scores. Note how the item "first" was listed last because it has the largest score.
  • Zset lets you to call the range and display the scores. All you need to do is add the WITHSCORE command in the end.
  • Zset also lets you to set the upper and lower limit of the score range. ZRANGEBYSCORE hellozset 0 450 WITHSCORES displays all items in hellozset with scores between 0 to 450, effectively excluding the "first" item.

Redis Pub/Sub

You can use the pub/sub (publish/subscribe) pattern in Redis to send and receive messages. The idea is to have one or more entities subscribe to a channel. Then a publisher sends messages to that channel. All subscribers will then receive it.

Here's a very basic version of it. Inside a redis-cli interface, let's subscribe to a channel:

SUBSCRIBE donuts

Now run a new redis-cli. This one will act like a publisher. Run:

PUBLISH donuts yummy

Pay attention to the first CLI (the subscriber). It will receive the "yummy" event. With pub/sub, you can subscribe to a channel (or multiple channels at the same time) and wait for a new published event.

What do we use Redis for?

Redis is an in-memory database with very low latency compared to a relational database like PostgreSQL. The important question is, "what do we use Redis for?"

You can use Redis for what a relational database cannot do best. You use relational database for what Redis cannot do best.

  1. Use Redis for a session cache. If you want to store a user session information outside of your server but don't want to store the entire session data in the Session Storage or cookies, you can use Redis. In a Redis server, create a hash object login_users: (you can call it anything) to store the login informations that can be called with a userId token from your cookie.

  2. Use Redis for a value cache. If you have a computationally intensive function, after running it once, save the result in the cache. The next time someone requested to run that function with the same parameters again, check if the cache value is already in Redis before requesting your main server to compute it.

  3. Use Redis to implement an expiration date. Suppose you want to keep the last 1,000,000 session information in the Redis server. Redis has a zset (sorted set) for these sort of tasks. When creating a new session information, assign a time score (Unix time stamp is perfect) to each session added. Have a daemon process to periodically check this zset and only keep the most recent 1,000,000 users with ZRANGE.

  4. Use Redis to cache HTML pages. Pages like /support pages are mostly static. Cache them with Redis instead so the server doesn't have to provide the page, freeing it to do more important stuff.

  5. Use Redis to keep track of votes like Stackoverflow upvotes. Again, zset is a good data type for this task. To display the top 50 most popular articles, run ZREVRANGE popularArticles: 0 49.

There are many other usages for Redis. Check out:

Love this? Find me on twitter!