Best Practices

Pub/Sub

Aside from data storage, Redis can be used as a Publisher/Subscriber platform. In this pattern, publishers can issue messages to any number of subscribers on a channel. These messages are fire-and-forget, in that if a message is published and no subscribers exists, the message evaporates and cannot be recovered.

Once subscribed to a channel, the client is put into subscriber mode and no commands can be issued by the client. In this way, the client has become read-only. Publishing has no such limitation.

More than one channel can be subscribed to at a time. Let’s start by subscribing to two channels weather and sports using the SUBSCRIBE command.

> SUBSCRIBE weather sports
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "weather"
3) (integer) 1
1) "subscribe"
2) "sports"
3) (integer) 2

In a separate client (a separate terminal for our example) we can publish items to either of these channels. We do this by running the PUBLISH command:

> PUBLISH sports oilers/7:leafs/1
(integer) 1

The first argument is the channel and the second argument is the message. The message can be anything, in this case, it’s an encoded sports score. It returns the number of clients that it will be delivered to. Back in the subscriber mode client, we’ll instantly see the message:

1) "message"
2) "sports"
3) "oilers/7:leafs/1"

The response has three elements: the notice that’s a message, followed by the channel and finally the message itself. The client returns to listening immediately after the message is received. Flipping back to the other we can publish another message:

> PUBLISH weather snow/-4c
(integer) 1

In the other client we’ll see the same format but with another channel and event:

1) "message"
2) "weather"
3) "snow/-4c"

Let’s issue publish to a channel that no one is subscribing to:

> PUBLISH currency CADUSD/0.787
(integer) 0

Since we don’t have any clients listening to the channel currency the return is 0. This message is now gone and clients that subsequently subscribe to the currency channel will not be notified of this message – the message was fired and how it has been forgotten.

Aside from subscribing to individual channels, Redis allows for pattern-based subscriptions. The glob-style patterns and are enabled by the PSUBSCRIBE command:

> PSUBSCRIBE sports:*

This will get messages for any channel that starts with “sports:*”. In the other client, issue the following commands:

> PUBLISH sports:hockey oilers/7:leafs/1
(integer) 1
> PUBLISH sports:basketball raptors/33:pacers/7
(integer) 1
> PUBLISH weather:edmonton snow/-4c
(integer) 0

Note how the first two commands returned 1 versus the last command which has a 0. Even though we have no direct subscribers of sports:hockey or sports:basketball , it is still picked up as being received by the pattern subscription.  Back on our subscribed client we can see the results are only returned for the channels that match the pattern.

1) "pmessage"
2) "sports:*"
3) "sports:hockey"
4) "oilers/7:leafs/1"
1) "pmessage"
2) "sports:*"
3) "sports:basketball"
4) "raptors/33:pacers/7"

This response is a little different from the straight SUBSCRIBE response as it has both the matched pattern (2) and the actual channel named (3).