What is pub/sub?

The pub/sub pattern is a key concept in software architecture and design for performing asynchronous communication between parties. But what is pub/sub, and how does pub/sub work in practice?

What is the pub/sub pattern? How does pub/sub work?

Pub/sub (which is short for "publish/subscribe") is a software messaging pattern for communicating asynchronously in serverless and microservices architectures.

To start using the pub/sub pattern, there are four important concepts that you need to know:

  • Message: A serialized, discrete unit of communication that is encoded to be exchanged between different parties.
  • Publisher: An application or other entity that is responsible for sending messages.
  • Subscriber: An application or other entity that receives messages from one or more publishers.
  • Topic: A channel that contains messages about a particular subject.

The most important idea behind pub/sub is that neither the sender nor the recipient(s) needs to be aware of the other's existence, which means that both can operate independently of each other. Publishers don't need to know who is subscribed to receive their messages, and subscribers don't need to know who is sending them messages.

If an application is interested in a particular topic, it simply needs to subscribe to that topic and will immediately begin receiving messages. This is different from the concept of message queues, in which messages are batched until they are retrieved by the recipient.

Pub/sub vs. observer pattern

The pub/sub pattern is often compared and contrasted with the observer pattern, another important software design messaging style.

In the observer pattern, a single object known as the "subject", or sometimes the "observable", is responsible for maintaining a list of its dependents, which are known as the "observers". When the subject changes state, all of the dependent observers are also updated automatically.

The observer pattern is an example of a "one-to-many" relationship: a single subject controls the behavior of many observers. By contrast, the pub/sub pattern is an example of a "many-to-many" relationship: publishers can send messages to multiple topics, and subscribers can receive messages from multiple publishers. In addition, both the subject and the observers are aware of each other in the observer pattern, whereas publishers and subscribers may not be in the pub/sub pattern.

Pub/sub benefits and use cases

The benefits of the pub/sub pattern include:

  • Efficiency: With the pub/sub pattern, there's no need for listeners to repeatedly "poll" for new messages from the publishers. Instead, messages are delivered instantaneously, which is a major advantage for real-time applications.
  • Scalability: The pub/sub pattern decouples publishers from subscribers, letting each application operate independently. This makes it easier to scale very large-scale systems, and to make changes to only part of the system.
  • Simplicity: Integrating different applications and handling communications between them is an infamously difficult task: each application represents a potential point of failure. Pub/sub removes much of this complexity by removing connections between individual applications, and replacing them with connections to different topics.

Thanks to these advantages, the pub/sub pattern is frequently implemented for use cases such as load balancing, event-driven architectures, and data streaming.

Pub/sub in Redis

Redis is an open-source, in-memory data structure store that is frequently used to implement NoSQL key-value databases, caches, and message brokers. This last use case means that Redis can be used as a pub/sub platform.

The PUBLISH command in Redis is used to publish a message to a particular channel. For example, the command below publishes the message "oilers/7:leafs/1" to the "sports" channel:

PUBLISH sports oilers/7:leafs/1

Similarly, the SUBSCRIBE command is used to subscribe to a particular channel:

SUBSCRIBE sports

Redis makes it easy to set up a simple pub/sub pattern. However, one complication with Redis is that it's not compatible with programming languages like Java out of the box. To ease the learning curve, many Java developers install third-party Redis Java clients such as Redisson.

The good news is that Redisson also includes pre-built functionality for building pub/sub patterns via the RTopic interface. Below is an example of pub/sub patterns in Redisson:

RTopic topic = redisson.getTopic("anyTopic");
topic.addListener(SomeObject.class, new MessageListener<SomeObject>() {
  @Override
  public void onMessage(String channel, SomeObject message) {
    //...
  }
});

// in another thread or JVM
RTopic topic = redisson.getTopic("anyTopic");
long clientsReceivedMessage = topic.publish(new SomeObject());

RTopic comes with asynchronous, reactive, and RxJava2 interfaces, so that you can use the programming model that best fits your needs. In addition, Redisson improves the availability of RTopic by automatically resubscribing listeners to topics if a Redis failover occurs.

Similar terms