Pub/Sub Messaging
In Redis, channels decouple producers from consumers. A publisher broadcasts to a channel without knowledge of its audience, while subscribers receive only the channels they follow. This topology eliminates polling: the server pushes messages to all connected clients as soon as they arrive.
Every push notification is an array whose structure depends on the event kind:
subscribe— Cofnirms a new subscription. The second element is the channel name; the third is the total number of channels currently subscribed.unsubscribe— Confirms removal. The second element is the channel; the third is the remaining subscription count. When this count reaches zero, the client exits pub/sub mode and may issue arbitrary Redis commands again.message— Carries payload data. The second element is the originating channel, and the third is the actual body.
Common channel commands include:
SUBSCRIBE news.sports news.tech
UNSUBSCRIBE news.sports
PUBLISH news.sports "Match started"
Calling UNSUBSCRIBE with no arguments drops every active subscription.
Primary-Replica Replication
Redis supports cascading replication: a single primary node can synchronize to multiple replicas, and those replicas may in turn act as parents to additional nodes, building a tiered cluster.
Consider a primary at 10.0.0.5 and a replica at 10.0.0.6.
Primary configuration:
bind 10.0.0.5
Replica configuration:
bind 10.0.0.6
replicaof 10.0.0.5 6379
After restarting both nodes, run INFO replication to verify the link. Writes issued against the primary:
SET greeting "hello world"
are automatically synchronized and visible on the replica:
GET greeting
Python Client Installlation
Install the latest redis package directly:
pip install redis
Or build from source:
tar -xzf redis-py.tar.gz
cd redis-py
python setup.py install
Interacting from Python
Import the client and open a connection:
import redis
try:
cache = redis.Redis(host='localhost', port=6379, decode_responses=True)
except Exception as err:
print(err)
Different data structures expose their own methods. For example, hash operations look like this:
cache.hset('profile:user:42', 'name', 'Alice')
cache.hget('profile:user:42', 'name')
To amortize round-trip cost, batch commands with a pipeline:
batch = cache.pipeline()
batch.set('counter:page:home', '0')
batch.incr('counter:page:home')
batch.get('counter:page:home')
results = batch.execute()
Encapsulating Common Operations
Because connection setup is identical across use cases, a thin wrapper keeps code DRY:
import redis
class StringCache:
def __init__(self, host='127.0.0.1', port=6379, db=0):
self._store = redis.Redis(
host=host, port=port, db=db,
decode_responses=True
)
def fetch(self, key):
value = self._store.get(key)
return value if value is not None else ""
def save(self, key, value, ttl_seconds=None):
self._store.set(key, value, ex=ttl_seconds)