How to use pub/sub in Redis
Last updated: Sep 02, 2024
Update (Dec. 17, 2023)
I’ve managed to deploy the project to render.com and use upstash.com for redis database. There are two applications that talk to each other - client (React) and server (GraphQL and Redis parts).
Here is a small GIPHY 📺 of the application in action:
And here you can play with it yourself.
Introduction
Oftentimes when working on an application that needs to be easy maintainable, scalable and performant, developers will go with Publish/Subscribe messaging pattern.
The idea behind it is simple, but powerful. We have senders called publishers. Their sole role is to send or publish messages. They don’t care about who is going to receive them or if someone will receive them at all. They just shoot and forget the messages. And they do that via so-called channels. Think of them as for example TV channels. We have Sport channels, Weather Forecasting channels, Cooking channels. Every publisher could send its messages to a certain channel, and whoever is subscribed for this channel will be able to receive these messages.
Here is where the subscribers come in play. They can subscribe to one or more channels and start receiving the messages broadcasted in there. As we already mentioned, the messages are to be sent and forgotten, which means that if a subscriber subscribes for a certain channel, all the messages that were sent previously in that channel are not going to be available to this subscriber.
Due to the nature of this kind of architecture we can easily achieve low coupling between the different components and provides a solid foundation for building robust and easy-to-maintain applications. For example, imagine a situation where we need to replace or improve the publishing part of our system, say add more publishers, more channels or so on. Since the two parts are isolated, meaning publishers don’t care about subscribers and vice versa, we could easily do that without worrying whether we are breaking some other part of the system. We just add the new publishers and then later, when a subscriber comes to the relevant channels, it just starts using them.
Redis
The initial idea behind Redis was to serve as in-memory cache solution, as an alternative of its ancestor Memcached. But nowadays it became many-in-one solution - it provides in-memory data structure store, key-value database, message brokering and so on. This makes it perfect candidate when building an application that needs really fast caching solution as well as some of the other features mentioned before. Especially if the performance of the app is crucial for its normal usage.
One of the biggest advantages when using Redis is the huge community and technical resources one can find online. A lot of these resources are free, also there are online platforms that have free tier offerings. Redis includes in its arsenal a cloud solution as well. If you want to try it yourself, you may go here and register a free account or use their initial coupon offering.
Pub/Sub in Redis
What is it?
Publish/Subscribe channels in Redis is one of the features I haven’t mentioned above but it’s already included in the last versions of Redis. This is their implementation of the aforementioned messaging pattern (Pub/Sub) where we have publishers and subscribers which exchange messages via channels. Let’s go briefly through it below and then we will see it in practice, in a small demo app I have prepared for you.
How does it work?
We have publishers, the producers of messages, we have the channels these messages are going through, and we have the subscribers - the receivers of the messages. Who receives what depends solely on who is subscribed for which channel.
Example
If we have created three publishers which will be publishing messages to three different channels. Let’s call them channels 1, 2 and 3. We also have three subscribers, let’s call them subscribers A, B and C. Now, let’s imagine subscriber A is listening for messages on all three channels, i.e. it is subscribed for them. And subscribers B and C are signed over channels 2 and 3. What this means is when either of the three publishers sends a message, subscriber A will receive it. And subscribers B and C will be receiving messages sent only by publishers 2 and 3, because they are listening only for messages on these channels (2 and 3).
Notice that we have two entities using a channel - one is sending, the other is receiving, but they are totally independent. And the messages being sent are not persisted - once they are sent by the publisher they are forgotten. The only entities that are subscribed at the moment of sending will get them.
How to use it?
There are a plethora of client libraries that could be used with Redis. There is a dedicated page where everybody could go and pick one, depending on the specific project needs or just on your preferred programming language. People at Redis also marked some of these repositories as recommended which makes the choice easier, if you are new to all this.
For our demo below, I used ioredis - a full-featured Redis client for Node.js. I chose this because the demo app UI is built with React and Node.js for my server code goes pretty well with it.
Demo
Show time!
The idea behind the demo application is to show visually how the pattern works.
What you will see when you open it for first the time is three buttons for publishing simple messages (news) in the three imaginary TV channels - Weather, Sport and Music. The cards below the publish buttons are the subscribers. Once you move your mouse cursor over any of them, it will flip to its back side and you will see three buttons. You may use each of these buttons to subscribe for the relevant channel. Once a subscriber is signed over a channel and you click on the icon or the publish button for this channel, you will see a sample news appearing on the front side of the card.
Play with different publishers/subscribers combinations and see the result.
I hope this will give you a better understanding of what was explained in the example above.
How to run it locally?
In order to install and run the demo application locally, please follow the steps below (all commands are considered to be run from the root project directory):
Run frontend
cd client yarn && yarn dev
Run backend
cd server && yarn yarn start
And finally use your local installation of Docker (if don’t have one, you may get it from here) to run this:
docker run -p 6379:6379 redislabs/redismod:preview
That’s probably the easiest way to have a running copy of Redis locally. The other option would be to use Redis Cloud directly and deploy the application online. This is an option I am still investigating and if I manage to do it, I will deploy the whole app and will let you know.
Closing
This article touches gently on the pub/sub messaging pattern subject, but what I think is important to remember is that whenever we want to build a highly performant application with a low coupled architecture and real-time like messaging features, we surely should consider using Publish/Subscribe pattern and maybe Redis in particular.
In fact a lot of the real life applications using Redis, one may find online, are dashboard based - meaning that usually there is a nice dashboard screen, showing different data, often being updated in real time. Imagine for example a system showing the road traffic in a specific area. This kind of software is a perfect candidate for leveraging the advantages of pub/sub. And in many cases this is achieved by using Redis.
In any case, we, as developers and engineers, always should be guided by the specific needs of the project we are working on and whenever we decide to introduce a new pattern or technology, to do it carefully and backed up by serious research.
← Go home