Raphael (PH) De Lio

Software Engineer

Understanding Pub/Sub in Redis

Besides being a database, Redis is also a message broker that supports typical pub/sub operations. In this story, we’ll dive into the world of Pub/Sub in Redis and explore its capabilities and limitations.

Pub/Sub in a nutshell

Pub/Sub stands for “Publish/Subscribe”. It is a pattern in computer programming that involves allowing messages to be sent from one component of an application to one or many other components without those components being directly connected or having a direct relationship with one another.

Think of it like a radio broadcaster. The “publisher” broadcasts audio, and the “subscribers” listen to the audio. The publisher does not need to know who the subscribers are, and the subscribers do not need to know who the publisher is. The only thing that matters is the message being broadcast.

Animated GIF of a broadcasting tower emitting signals, represented by concentric lines radiating outward, symbolizing communication or data transmission.

In pub/sub, components can send messages to a central “topic” or “channel”, and other components can subscribe to that channel to receive those messages. This allows for decoupled communication between components and makes it easier to manage the flow of information in a complex system.

Pub/Sub in Redis

Redis implements the Pub/Sub pattern by providing a simple and efficient messaging system between clients. In Redis, clients can “publish” messages to a named channel, and other clients can “subscribe” to that channel to receive the messages.

When a client publishes a message to a channel, Redis delivers that message to all clients that are subscribed to that channel. This allows for real-time communication and the exchange of information between separate components of an application.

Animated GIF of a mailbox in the center sending messages to multiple clients represented by cartoon avatars with ‘CLIENT’ labels, illustrating message broadcasting or communication in a distributed system.

Redis Pub/Sub provides a lightweight, fast, and scalable messaging solution that can be used for various use cases, such as implementing real-time notifications, sending messages between microservices, or communicating between different parts of a single application.

Synchronous Communication

Redis Pub/Sub is synchronous. Subscribers and publishers must be connected at the same time in order for the message to be delivered.

Think of it as a radio station. You are able to listen to a station while you’re tuned into it. However, you’re incapable of listening to any message broadcast while your radio was off. Redis Pub/Sub will only deliver messages to connected subscribers.

This means that if one subscriber loses connection and this connection is restored later on, it won’t receive any missed messages or be notified about them. Therefore, it limits use cases to those that can tolerate potential message loss.

Animated GIF showing a Redis Channel broadcasting a message, ‘The match started! It’s Brazil against Argentina!’ from a sender at the top to three listeners below. Each listener reacts with comments like ‘Go Neymar!’, ‘Cool!’, and ‘Nice!’, symbolizing a publish-subscribe (Pub/Sub) messaging system in Redis.

Fire & Forget

Fire & Forget is a messaging pattern where the sender sends a message without expecting an explicit acknowledgment from the receiver that the message was received. The sender simply sends the message and moves on to the next task, regardless of whether or not the message was actually received by the receiver.

An animated GIF illustrating a Pub/Sub system. A publisher on the left sends messages to a mailbox in the center, representing a Redis channel. On the right, two subscribers react: one says, ‘I’m receiving the messages, but I cannot tell the receiver I am!’ while the other says, ‘I stopped receiving the messages, but the receiver doesn’t know about it,’ demonstrating the decoupling nature of Pub/Sub communication.

Redis Pub/Sub is considered a “Fire & Forget” messaging system because it does not provide an explicit acknowledgment mechanism for confirming that a message was received by the receiver. Instead, messages are broadcast to all active subscribers, and it is the responsibility of the subscribers to receive and process the messages.

Fan-out Only

Redis Pub/Sub is fan-out only, meaning that when a publisher sends a message, it is broadcast to all active subscribers. All subscribers receive a copy of the message, regardless of whether they are specifically interested in the message or not.

No relation to the keyspace

Additionally, Pub/Sub has no relation to the key space. This means that a message published on database 10 will be heard by a subscriber on database 1. If you need scoping, Redis suggests prefixing the channel name (prod_mychannel, test_mychannel).

Putting our hands in the fire

Redis message brokering is implemented through the PUBLISH and SUBSCRIBE commands. The PUBLISH command allows the user to send a message to a specific channel, and the SUBSCRIBE command allows the user to listen to messages on a specific channel. This makes it easy to implement a publish-subscribe pattern in your application.

Channels are not explicitly created by the user. The channels are created automatically when the first message is published or a client subscribes to them.

In this example, we’ll open three connections with the same Redis server. Each connection will act as a different client.

Two of the connections will subscribe to the crazy_channel, while the third one will publish messages to the same channel.

By doing that, we expect our messages to be delivered to both subscribers as soon as they’re published by the publisher.

Connecting to the Redis server

If you don’t have an instance of Redis already running, make sure you check my tutorial on how to run Redis locally with Docker:

Open three terminal windows and connect to your Redis server in each one of them. If you followed my previous tutorial, you can do it by running the following command:

docker exec -it redis-stack redis-cli
A screenshot showing three terminal windows where a user executes the Redis CLI inside a Docker container using the command docker exec -it redis-stack redis-cli. Each terminal connects to 127.0.0.1:6379, the default Redis port, demonstrating multiple sessions accessing Redis.

Subscribing to a channel

To subscribe to a channel, we need to issue the SUBSCRIBE command with the channel’s name as the argument. In the first two windows, let’s issue the following command:

SUBSCRIBE crazy_channel
Animated GIF showing multiple terminal windows connected to a Redis server at 127.0.0.1:6379 using the command docker exec -it redis-stack redis-cli. Each terminal window executes commands interactively, demonstrating concurrent Redis CLI sessions running on a Docker container.

Publishing to a channel

You can publish a message to a channel using the PUBLISH command. The PUBLISH command takes two arguments: the name of the channel and the message to be sent.

In the third window, let’s publish “This channel is hella crazy”. We can do it by issuing the following command

PUBLISH crazy_channel "This channel is hella crazy"

Let’s publish another message:

PUBLISH crazy_channel "Hell yeah! It is!"
Animated GIF showing multiple terminal windows subscribing to a Redis channel named crazy_channel using the command SUBSCRIBE crazy_channel. Each terminal window connects to Redis via docker exec -it redis-stack redis-cli and begins reading messages, displaying the subscription confirmation and message count.

Crazy! We can see that it worked. As soon as we hit enter, our messages popped up in the clients that were subscribing to our channels. Let’s analyze what happened there.

You can see that every time a message popped up, three lines were printed into the terminal. We ended up with three blocks of three lines each.

Each of these blocks represents an event notification. Each event notification is a tuple that consists of three elements:

  1. The type of the event.
  2. The channel that the event applies to.
  3. Additional data associated with the event.

In this example, we are subscribing to the channel “crazy_channel”, so the first event notification is a “subscribe” event, which indicates that we have successfully subscribed to the channel. The second element is the channel name, “crazy_channel”, and the third element is the number of channels we are currently subscribed to, which is 1.

The following event notifications are “message” events, which indicate that messages have been received on the subscribed channel. The second element is the channel name, “crazy_channel”, and the third element is the actual message data, which is a string representing the message content.

Other commands

When subscribing via the Redis command line interface, you cannot issue any other commands to your server. However, if you’re subscribing through another interface, telnet, for example, you can still issue commands that are related to message subscription. Here are the commands allowed in the context of a subscriber:

CommandDescriptionExample
SUBSCRIBESubscribes the client to one or more channelsSUBSCRIBE channel_name
PSUBSCRIBESubscribes the client to one or more channels using pattern_matchingPSUBSCRIBE channel_pattern
SSUBSCRIBESubscribes the client to one more channels in a Redis Cluster shardSSUBSCRIBE channel_name
UNSUBSCRIBEUnsubscribe the client from one or more channelsUNSUBSCRIBE channel_name
PUNSUBSCRIBEUnsubscribes the client from one or more channels using pattern matchingPUNSUBSCRIBE channel_pattern
SUBSUBSCRIBEUnsubscribes the client from one or more channels in a Redis Cluster shardSUBSUBSCRIBE channel_name
PINGTests the connection to the Redis ServerPING
RESETResets the connection to the Redis serverRESET
QUITCloses the connection to the Redis ServerQUIT

Conclusion

Redis provides a simple and powerful solution for real-time messaging systems through its Pub/Sub functionality.

It’s lightweight, easy to implement, and integrate into existing systems. It can also support a large number of subscribers and handle high volumes of messages with low latency. Besides that, messages are delivered in the order that they are published.

It’s important to note that the use cases are limited to those that can tolerate message loss, and that don’t require explicit acknowledgment of messages by the receiver. These limitations should be considered when determining the suitability of Redis Pub/Sub as a message broker for a particular use case.

However, these limitations can be overcome when using Redis Streams, the subject of our next story:

Leave a Reply

Your email address will not be published. Required fields are marked *