Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
Redis 客户端可以订阅任意数量的频道。
redis的发布订阅类似于消息队列的主题模式。
client1,client2和client5订阅了channel1
那么当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
订阅(根据规则)
规则支持通配符
通配符中?表示1个占位符,表示任意个占位符(包括0),?表示1个以上占位符。
不会收到订阅之前就发布到该频道的消息
PSUBSCRIBE pattern [pattern ...]
返回值
为1表示被订阅者所接受
为0表示没有被订阅者接收
client1订阅
127.0.0.1:6379> psubscribe c? b* d?*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "c?"
3) (integer) 1
1) "psubscribe"
2) "b*"
3) (integer) 2
1) "psubscribe"
2) "d?*"
3) (integer) 3
client2发布
127.0.0.1:6379> PUBLISH c1 hello
(integer) 1
127.0.0.1:6379> PUBLISH c11 hello
(integer) 0
127.0.0.1:6379> PUBLISH b11 hello
(integer) 1
127.0.0.1:6379> PUBLISH d hello
(integer) 0
127.0.0.1:6379> PUBLISH d1 hello
(integer) 1
127.0.0.1:6379> PUBLISH d2 hello
(integer) 1
client1消费消息
127.0.0.1:6379> psubscribe c? b* d?*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "c?"
3) (integer) 1
1) "psubscribe"
2) "b*"
3) (integer) 2
1) "psubscribe"
2) "d?*"
3) (integer) 3
1) "pmessage"
2) "c?"
3) "c1"
4) "hello"
1) "pmessage"
2) "b*"
3) "b11"
4) "hello"
1) "pmessage"
2) "d?*"
3) "d1"
4) "hello"
1) "pmessage"
2) "d?*"
3) "d2"
4) "hello"
订阅(指定名字)
不会收到订阅之前就发布到该频道的消息
SUBSCRIBE channel [channel ...]
查看订阅与发布系统状态。
PUBSUB subcommand [argument [argument ...]]
发布消息
PUBLISH channel message
退订(根据规则)
PUNSUBSCRIBE [pattern [pattern ...]]
退订(指定名字)
UNSUBSCRIBE [channel [channel ...]]
示例
我们开两个会话窗口,开启两个redis-cli连接一个redis-server。
订阅
client1订阅anin-chat这个channel
127.0.0.1:6379> SUBSCRIBE anin-chat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "anin-chat"
3) (integer) 1
发布
client2往anin-chat发布两条消息。
127.0.0.1:6379> PUBLISH anin-chat hello~anin
(integer) 1
127.0.0.1:6379> PUBLISH anin-chat yes!
(integer) 1
127.0.0.1:6379>
消费
我们发现client1收到了client2发的消息。
1) "message"
2) "anin-chat"
3) "hello~anin"
1) "message"
2) "anin-chat"
3) "yes!"
注意
- 使用psubscribe命令可以重复订阅同一个频道,如客户端执行了psubscribe c? c?。这时向c1发布消息客户端会接受到两条消息,而同时publish命令的返回值是2而不是1。同样的,如果有另一个客户端执行了subscribe c1 和psubscribe c?的话,向c1发送一条消息该客户顿也会受到两条消息(但是是两种类型:message和pmessage),同时publish命令也返回2.
- punsubscribe命令可以退订指定的规则,用法是: punsubscribe [pattern [pattern …]],如果没有参数则会退订所有规则。
- 使用punsubscribe只能退订通过psubscribe命令订阅的规则,不会影响直接通过subscribe命令订阅的频道;同样unsubscribe命令也不会影响通过psubscribe命令订阅的规则。另外需要注意punsubscribe命令退订某个规则时不会将其中的通配符展开,而是进行严格的字符串匹配,所以punsubscribe 无法退订c规则,而是必须使用punsubscribe c*才可以退订。
**
127.0.0.1:6379> PSUBSCRIBE c? c?*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "c?"
3) (integer) 1
1) "psubscribe"
2) "c?*"
3) (integer) 2
1) "pmessage"
2) "c?*"
3) "c1"
4) "hello"
1) "pmessage"
2) "c?"
3) "c1"
4) "hello"
127.0.0.1:6379> PUBLISH c1 hello
(integer) 2
缺点
- PubSub 的生产者来一个消息会直接传递给消费者。如果没有消费者,消息会直接丢弃。如果有多个消费者,一个消费者突然挂掉,生产者会继续发送消息,另外的消费者可以持续收到消息。但是挂掉的消费者重新连上后,断连期间的消息会彻底丢失;
- 如果 Redis 停机重启,PubSub 的消息是不会持久化