Redis provides a Pub/Sub api that scales well and allows for quick real time connections. Real time apps are very popular, so redis can help you solve these business problems. If you are familiar with the popular socket.io, you will see in their docs an option to use Redis as an adapter to scale. In this article, we will learn how to use PubSub in Redis with Python.
Just to give a more clear view, let's say you have the following setup with some microservices because you have scaled to many users
In this scenario, you can have a number of users connect to either API server app which allows you to handle more connections than a single server. Then, you can have redis pub/sub send quick communication between the three servers, the API servers and the DB. This allows you to quickly add more backend servers to scale while keeping connections to the client.
For setting up Redis, I would recommend using a service for you in prod. Azure for example, has a great redis service that scales easily. However, you will want to learn redis and eventually how to scale it yourself. This will help with debugging cloud services or eventually, saving money and not using them.
We will start our intro to redis via using docker compose. Create a docker-compose.yml
file and add the following.
version: "3.2"
services:
redis:
image: "redis:alpine"
command: redis-server
ports:
- "6379:6379"
volumes:
- $PWD/redis-data:/var/lib/redis
- $PWD/redis.conf:/usr/local/etc/redis/redis.conf
environment:
- REDIS_REPLICATION_MODE=master
Ensure you have docker installed and run
docker-compose up
In python, the main used redis module is called redis-py
and can be installed using the follows.
pip install redis
Let's start be creating a subscriber to list to messages. To start, we will need to import redis and connect to our server. We will also need the time library for an infinite loop later.
# subscriber.py
import redis
import time
r = redis.Redis(host='localhost', port=6379, db=0)
Now, let's create an instance of PubSub from the redis library and use the subscribe
method to subscribe to two different channels.
p = r.pubsub()
p.subscribe("my-channel-1", "my-channel-2")
Finally, we will create an infinite loop and use the get_message
command. If we receive a message, we will print it out.
while True:
message = p.get_message()
if message:
print(message)
time.sleep(0.01)
Open a terminal and run python subscriber.py
to start the listener.
Here is the full file for context.
# subscriber.py
import redis
import time
r = redis.Redis(host='localhost', port=6379, db=0)
p = r.pubsub()
p.subscribe("my-channel-1", "my-channel-2")
while True:
message = p.get_message()
if message:
print(message)
time.sleep(0.01)
The publisher is much simpler. We simply connect to our redis instance, then use the publish
method to send a message.
# publisher.py
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
r.publish('my-channel-1', 'my data')
Open a new terminal tap and run python publisher.py
. This will send a message to our other python script.
Redis also provides a way to pattern match when using the publish and subsribe feature. Let's say we had the following publisher sending events for multiple users.
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
r.publish('user-1', 'my data')
r.publish('user-2', 'my data')
We can subscribed to all user events using the psubscribe
method which stands for pattern subsrcibe. Here we subscribe to user-*
which means all channels with the prefix user-
# subscriber.py
import redis
import time
r = redis.Redis(host='localhost', port=6379, db=0)
p = r.pubsub()
p.subscribe("user-*")
while True:
message = p.get_message()
if message:
print(message)
time.sleep(0.01)