Redis is a powerful key-value database, perfect for caching and in-memory (ephemeral) storage of data.
In this issue of Bytesized, we'll dig into the what, the why, and the how of Redis, and give you the tools you need to get started deploying your first Redis instance.
Redis is highly performant: written entirely in C (and open-source on GitHub), it fits in the space between databases — persistent, rock-solid places to store the bulk of your app's data — and in-app memory — small variables or constants you hold onto while handling a request. Instead, Redis excels at situations where you need to cache a value between requests or between users.
Let's start with a quick introduction to Redis — how to set up your first Redis instance, and issuing commands — before looking at best practices, stories of Redis saving the day in production, and what to check out next as you master Redis and use it in your workflows.
A brief guide to Redis
Installing Redis is generally pretty easy, regardless of your platform. Using your package manager of choice (I'll use
homebrew, on Mac), install the Redis package:
$ brew install redis
With Redis installed, you'll need to then start the Redis service on your machine. If you're familiar with your operating system's configuration system, you may be able to use something like macOS's
launchctl or any number of other Linux solutions to this problem (see "Installing Redis more properly" in the Redis Quick Start) to start up Redis when your computer boots up. For now, we'll just open a new shell window and run the
$ redis-server 30851:C 08 Feb 2021 11:42:00.621 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
The easiest way to begin working with Redis is through the CLI, which allows you to issue commands directly to your Redis server from in your terminal. Run
redis-cli, and let's use the
PING command to ensure that we can talk to our Redis server from the command-line client:
$ redis-cli redis> PING PONG
PING is the first Redis command on our list to check out today. There's a lot more of them (see the "Commands" page — there's 280+ to dig into!), but we'll focus on the basic datasets and how to retrieve them in our brief lesson today.
Setting and getting basic values
SET command, we can provide a key-value pair to Redis to persist. For instance, if I want to store the name of my newsletter, I'll run:
redis> SET newsletter "Bytesized" OK
In doing so, I've set the key
newsletter to the value
Bytesized. Values in Redis are always strings — that means that you'll often coerce values into strings if you're working with Redis as part of a larger application.
With our key set, we want to get it back from the Redis server. The
GET command does this:
redis> GET newsletter "Bytesized"
If you try to
GET a key that doesn't exist, you'll get a
nil value back:
redis> GET newsletter_name (nil)
One final piece of magic with
SET is providing expiration values. For instance, I could set the value
currently_working_on to some value, and expire it in 60 seconds. This is possible using a slight variation on
SETEX, which accepts an optional number of seconds to expire on in the format
SETEX key seconds value:
redis> SETEX currently_working_on 60 "Writing a Redis blog post" OK
Once my key is set, I can use
GET to get the current value. I can also use
TTL to see how many seconds there are until the key expires:
redis> GET currently_working_on "Writing a Redis blog post" redis> TTL currently_working_on (integer) 20
Once the key expires, calling
GET will return
nil, as if the key wasn't ever set:
redis> GET currently_working_on (nil)
Basic data structures
On top of basic string values, Redis also has commands for building around more complex data structures. The most classic of those is the list — a set of values that can quickly be retrieved and written to. The
LPUSH command takes a key, and a value to push onto the beginning of the list at that key. The
RPUSH command is similar: instead of pushing to the beginning of the list, it'll add it to the end. The response will be the total size of the list:
LRANGE command is analogous to
GET for standard key-value pairs, allowing you to get a list of values from a key. Instead of just taking a key, it also takes a pair of indexes,
stop, which allow you to specify how many items you want out of the list. Passing a matching pair of
stop indexes will get a single value (for instance,
0 0 meaning "start and stop at the first index,
0"), and providing negative values will start from the end of the list:
There's a ton of other data structures in Redis — hashes, sets (lists that enforce unique values), and more. Check out the "Redis Data Structures" post linked below to learn more about how they differ from each other, and why you might pick one in a certain situation over the others available.
I was surprised to find out that even with Redis' ubiquity in high-availability circles, it didn't have many "back to basics" tutorials to show you how to write simple key-value pairs, and start to delve into data structures like lists. Now that we've taken a quick look at how to get up and running with it, let's dive deeper into understanding Redis, with some tutorials and blog posts, as well as some use-cases and proof-of-concepts to show you how you might use it in production.
This tutorial from Redis' creator, Salvatore Sanfilippo, shows how to build a simple Twitter clone in just PHP and Redis. Even if you don't know PHP (like me), the dive into how to model Twitter or something like it with Redis is a useful way to transfer existing knowledge (Twitter, and how it would be structured in a traditional database) to new things (how Redis stores and handles data).
In this video from Traversy Media, Brad Traversy dives into the fundamentals of Redis, including understanding the Redis CLI, the data types available in the tool, and how to persist your Redis data using snapshots.
On the topic of data types and structures in Redis, this blog post from RedisGreen covers the data structures in Redis, which serve different use-cases and have different performance characteristics to be aware of.
As you begin to use Redis in earnest, you'll learn quickly that how you structure your data tends to be one of the most important concerns you'll have. This blog post covers common pitfalls with picking good keys for your data, and how to develop better instincts around key lookups as a common performance bottleneck.
Use-cases and proof-of-concepts
ObjectRocket writes about the top five use-cases for Redis, using the data structures available and utilizing their performance characteristics to fit the situation:
- Session Cache
- Full Page Cache
This article from High Scability, published in 2014, outlines the details of a technical talk from a member of Twitter's cache team. In it, she covers how Redis is used throughout Twitter to handle extreme amounts of traffic (~30 million queries per second). If you want to watch the video itself, you can find it on YouTube below:
Redis works with basically any programming language. Because of the simple primitives it provides for interfacing with the Redis server, there's clients for basically every language and situation. The