Pub/Sub 指南
SUBSCRIBE 与 PUBLISH
已订阅的客户端只能运行 SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE、PING 和 RESET 命令。
# Terminal 1: subscriber
SUBSCRIBE news:sports news:tech
# Terminal 2: publisher
PUBLISH news:sports "Team wins championship!"
PUBLISH news:tech "New framework released"
# Subscriber receives messages in format:
# 1) "message"
# 2) "news:sports"
# 3) "Team wins championship!"
# Subscribe to multiple channels
SUBSCRIBE ch1 ch2 ch3
# Unsubscribe
UNSUBSCRIBE news:sports # leave one channel
UNSUBSCRIBE # leave all channels
模式订阅(PSUBSCRIBE)
# Subscribe with glob pattern
PSUBSCRIBE news:* # all news channels
PSUBSCRIBE user:[0-9]* # channels matching user:NNN
PSUBSCRIBE h?llo # hello, hallo, hxllo ...
# Received message format (pmessage):
# 1) "pmessage"
# 2) "news:*" <- matched pattern
# 3) "news:sports" <- actual channel
# 4) "Team wins!" <- payload
PUNSUBSCRIBE news:* # remove pattern subscription
# List active subscriptions
PUBSUB CHANNELS # all active channels
PUBSUB CHANNELS news:* # filtered
PUBSUB NUMSUB news:sports news:tech # subscriber counts
PUBSUB NUMPAT # number of pattern subscriptions
键空间通知
订阅 Redis 命令在键上触发的事件(如 SET、EXPIRE、DEL)。
# Enable keyspace notifications in redis.conf or at runtime
# K = Keyspace events E = Keyevent events
# g = generic $ = strings l = lists z = sorted sets
# x = expired d = stream
CONFIG SET notify-keyspace-events "KEA" # enable all
# Subscribe to keyspace channel for key "mykey"
SUBSCRIBE __keyspace@0__:mykey
# Subscribe to all expired key events
SUBSCRIBE __keyevent@0__:expired
# Subscribe to all SET operations
SUBSCRIBE __keyevent@0__:set
# Example: track session expiry
SUBSCRIBE __keyevent@0__:expired
# Receives channel: __keyevent@0__:expired
# message: session:abc123
Node.js 发布/订阅示例
// Using ioredis (separate connections required for sub/pub)
const Redis = require("ioredis");
const pub = new Redis();
const sub = new Redis();
// Subscribe
sub.subscribe("chat:room1", (err, count) => {
console.log(`Subscribed to ${count} channels`);
});
sub.on("message", (channel, message) => {
console.log(`[${channel}] ${message}`);
});
// Publish
await pub.publish("chat:room1", JSON.stringify({
user: "alice",
text: "Hello!"
}));
// Pattern subscribe
sub.psubscribe("chat:*", (err, count) => {});
sub.on("pmessage", (pattern, channel, message) => {
console.log(`Pattern: ${pattern}, Channel: ${channel}`);
});
发布/订阅与流对比
| 特性 | Pub/Sub | Streams (XADD/XREAD) |
|---|---|---|
| 消息持久化 | 否(即发即忘) | 是(存储在日志中) |
| 消费者组 | 否 | 是 |
| 重放消息 | 否 | 是 |
| 离线消费者 | 会错过消息 | 从上次位置读取 |
| 适用场景 | 实时通知 | 任务队列、事件溯源 |