Skip to content

8. Pub/Sub

8.1 Pub/Sub Pattern

📻 Analogy: Pub/Sub is like a radio station — subscribers to a channel (SUBSCRIBE) all receive the same broadcast (PUBLISH), but if you're not listening, the message is lost.

Open two redis-cli terminals:

bash
# Terminal A: subscribe to channels
SUBSCRIBE news:tech news:sports
bash
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news:tech"
3) (integer) 1
1) "subscribe"
2) "news:sports"
3) (integer) 2
bash
# Terminal B: publish messages
PUBLISH news:tech "Redis 7.4 officially released! New features supported..."
PUBLISH news:sports "2024 Euro Cup final results are out"
bash
(integer) 1
(integer) 1
bash
# Terminal A receives messages:
1) "message"
2) "news:tech"
3) "Redis 7.4 officially released! New features supported..."
1) "message"
2) "news:sports"
3) "2024 Euro Cup final results are out"
bash
# Pattern subscription (wildcard)
PSUBSCRIBE news:*

# Unsubscribe
UNSUBSCRIBE news:tech
PUNSUBSCRIBE news:*

⚠️ Note: Pub/Sub messages are NOT persisted! If a subscriber goes offline, messages published during that time will be lost. For reliable message delivery, use Stream.

8.2 Stream Message Queue (Reliable Version)

Compared to Pub/Sub, Stream's advantages: message persistence, consumer groups, ACK acknowledgment mechanism, and support for replaying past messages.

bash
# Create consumer group
XGROUP CREATE orders order_group 0 MKSTREAM

# Producer: send order messages
XADD orders * order_id "ORD_1001" product "Phone" amount 4999
XADD orders * order_id "ORD_1002" product "Earbuds" amount 299
XADD orders * order_id "ORD_1003" product "Watch" amount 1999

# Consumer 1 reads
XREADGROUP GROUP order_group worker1 COUNT 2 STREAMS orders >

# Consumer 2 reads
XREADGROUP GROUP order_group worker2 COUNT 2 STREAMS orders >

# Acknowledge message processed
XACK orders order_group "1704067200000-0"

# View Stream info
XINFO STREAM orders
bash
OK
"1704067200000-0"
"1704067200100-1"
"1704067200200-2"
1) 1) "orders"
   2) 1) 1) "1704067200000-0"
         2) 1) "order_id"
            2) "ORD_1001"
            3) "product"
            4) "Phone"
            5) "amount"
            6) "4999"
      2) 1) "1704067200100-1"
         2) 1) "order_id"
            2) "ORD_1002"
            3) "product"
            4) "Earbuds"
            5) "amount"
            6) "299"
1) 1) "orders"
   2) 1) 1) "1704067200200-2"
         2) 1) "order_id"
            2) "ORD_1003"
            3) "product"
            4) "Watch"
            5) "amount"
            6) "1999"
(integer) 1
1) "length"
2) (integer) 3
3) "first-entry"
4) 1) "1704067200000-0"
   2) ...
5) "last-entry"
6) 1) "1704067200200-2"
   2) ...