发布与订阅
Redis的发布与订阅功能可以让客户端通过广播方式,将消息同时发送给可能存在的多个客户端,并且发送消息的客户端不需要指定接收消息的客户端的具体信息,也就是说发送消息的客户端与接收消息的客户端没有直接的联系。
在Redis中,客户端可以通过订阅特定的频道(channel)来接收发送至该频道的消息,我们把这些订阅频道的客户端称为订阅者(subscriber),把发送消息给频道的客户端称为发送者(publisher)。一个频道可以有多个订阅者,而一个订阅者也可以订阅多个频道。
命令速查表
命令 | 用法及参数 | 说明 |
---|---|---|
PUBLISH | PUBLISH channel message | 将一条消息发送给特定频道 |
SUBSCRIBE | SUBSCRIBE channel [channel channel ... ] | 订阅一个或多个频道 |
UBSUBSCRIBE | UNSUBSCRIBE [channel channel ... ] | 退订指定的频道,如果未指定频道,则退订当前客户端订阅的所有频道 |
PSUBSCRIBE | PSUBSCRIBE pattern [pattern pattern ... ] | 订阅一个或多个模式 |
PUNSUBSCRIBE | PUNSUBSCRIBE [pattern pattern ... ] | 退订一个或多个模式 |
PUBSUB CHANNELS | PUBSUB CHANNELS [pattern] | 查看目前被订阅的频道 |
PUBSUB NUMSUB | PUBSUB NUMSUB [channel channel ... ] | 查看任意多个给定频道的订阅者数量 |
PUBSUB NUMPAT | PUBSUB NUMPAT | 查看目前被订阅模式的数量 |
命令详解
PUBLISH:向频道发送消息
使用PUBLISH命令,将一条消息发送给特定频道:
PUBLISH channel message
PUBLISH命令会返回接受到消息的客户端的数量作为返回值。
127.0.0.1:6379> PUBLISH "test" "hello world"
(integer) 3
复杂度:
O
(
N
+
M
)
O(N+M)
O(N+M),其中
N
N
N为给定频道的订阅者数量,而
M
M
M为服务器目前被订阅的模式总数量。
版本要求:Redis 2.0.0版本开始可用。
SUBSCRIBE:订阅频道
通过执行SUBSCRIBE命令,可以让客户端订阅给定的一个或多个频道:
SUBSCRIBE channel [channel channel ... ]
SUBCRIBE命令在每次成功订阅一个频道之后,都会向执行命令的客户端返回一条订阅消息,消息包含了被成功订阅的频道以及客户端目前已订阅的频道数量。
127.0.0.1:6379> subscribe "test"
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "test"
3) (integer) 1
- 消息的第一个元素是 “subscribe” 表示这是由 SUBSCRIBE 命令引发的订阅消息而不是普通客户端发送的频道消息。
- 消息的第二个元素记录了被订阅频道的名字 “test”
- 消息的最后一个元素是数字 1,表示客户端目前只订阅了一个频道
接受频道消息
与订阅消息一样,频道消息也是由3个元素组成的:
- 消息的第1个元素为 message ,用于表明该消息是一条频道消息而不是非订阅消息;
- 消息的第2个元素为消息的来源频道,用于表明该消息来源于哪个频道;
- 消息的第3个元素为消息的正文,也就是消息的内容;
127.0.0.1:6379> publish "test" "hello world"
(integer) 1
1) "message"
2) "test"
3) "hello world"
复杂度:
O
(
N
)
O(N)
O(N),其中
N
N
N为用户输入的消息数量。
版本要求:Redis 2.0.0版本开始可用。
UBSUBSCRIBE:退订频道
用户在使用SUBSCRIBE命令订阅一个或多个频道之后,如果不想再接收某个频道的消息,那么可以使用UBSUBSCRIBE命令退订指定的频道:
UNSUBSCRIBE [channel channel ...] ]
UNSUBSCRIBE命令允许用户给定任意多个频道。如果用户没有指定任何频道,直接以无参方式执行,那么命令将退订当前客户端已经订阅的所有频道。
客户端在每次退订之后,都会收到服务器发来的退订消息,这条消息由3个元素组成:
- 第1个元素是 “unsubscribe”,表明该消息是一条退订消息;
- 第2个元素是被退订频道的名字;
- 第3个元素是客户端在执行退订之后,目前仍在订阅的频道数量;
注意:虽然Redis提供了退订频道的UNSUBSCRIBE命令,但由于各个客户端对于发布与订阅的功能支持不同,所以并非所有的客户端都可以使用UNSUBSCRIBE命令来执行退订操作。例如Redis自带的命令行客户端 redis-cli 在执行SUBSCRIBE命令后进入阻塞状态,无法再执行其他命令,用户只能通过 Ctrl + C进行强制退出redis-cli程序。
复杂度:
O
(
N
)
O(N)
O(N),其中
N
N
N为服务器目前拥有的订阅者数量。
版本要求:Redis 2.0.0版本开始可用。
PSUBSCRIBE:订阅模式
用户可以通过执行 PSUBSCRIBE 命令让客户端订阅给定的一个或多个模式:
PSUBSCRIBE pattern [pattern pattern ... ]
其中 pattern 参数可以是一个全局风格的匹配符,如:“test.*” 表示可以接收所有以 “test.” 为前缀的频道,而 “test.[ie]t” 模式可以匹配 “test.it” 或 “test.et” 频道。
与SUBSCRIBE命令一样,PSUBSCRIBE命令在成功订阅一个模式之后,也会返回相应的订阅消息,这条消息由3个元素组成:
- 第1个元素是 psubscribe ,表示这条消息是由 PSUBSCRIBE 命令引发的订阅消息;
- 第2个元素是被订阅的模式;
- 第3个元素是客户端目前已订阅的模式数量;
127.0.0.1:6379> psubscribe "test.[ie]t"
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "test.[ie]t"
3) (integer) 1
客户端在订阅模式之后,就会收到所有与模式相匹配的频道的消息,我们把这些消息称为模式消息。模式消息与之前的频道消息有些不同,这个消息由4个元素组成:
- 消息的第1个元素为 “pmessage”,它表示这是一条模式消息而不是订阅消息或频道消息;
- 消息的第2个元素为被匹配的模式;
- 消息的第3个元素则是与模式相匹配的频道;
- 消息的第4个元素为消息的正文内容;
127.0.0.1:6379> publish "test.it" "test pattern1"
(integer) 1
1) "pmessage"
2) "test.[ie]t"
3) "test.it"
4) "test pattern1"
复杂度:
O
(
N
)
O(N)
O(N),其中
N
N
N为用户给定的模式数量
版本要求:Redis 2.0.0版本开始可用。
PUNSUBSCRIBE:退订模式
与退订频道的 UNSUBSCRIBE 命令类似,Redis也提供了用于退订模式的 PUNSUBCRIBE 命令:
PUNSUBSCRIBE [pattern pattern ... ]
与退订频道一样,如果 PUNSUBSCRIBE 命令未指定任何模式,那么将退订当前客户端所有订阅的模式。
同样的在各个客户端中对于 PUNSUBSCRIBE 命令的支持不同,Redis的redis-cli客户端中无法使用该命令。
复杂度:
O
(
N
∗
M
)
O(N*M)
O(N∗M),其中
N
N
N为用户给定的模式数量,而
M
M
M为服务器目前被订阅的模式数量。
版本要求:Redis 2.0.0版本开始可用。
PUBSUB:查看发布与订阅相关信息
通过使用 PUBSUB 命令,用户可以查看发布与订阅的相关信息。PUBSUB 命令目前有3个子命令可用,这3个子命令可以分别用查看不同的信息。
查看被订阅的频道
使用 PUBSUB CHANNELS 命令列出目前被订阅的所有频道,如果给定了可选项 pattern 参数,那么命令只会列出与给定模式匹配的频道:
PUBSUB CHANNELS [pattern]
查看频道的订阅者数量
用户可以使用 PUBSUB NUMSUB 命令来查看任意多个给定频道的订阅者数量:
PUBSUB NUMSUB [channel channel ... ]
查看被订阅模式的总数量
使用 PUBSUB NUMPAT 命令可以查看目前被订阅模式的数量:
PUBSUB NUMPAT
复杂度:PUBSUB CHANNELS命令的复杂度为 O ( N ) O(N) O(N),其中 N N N为服务器目前被订阅的频道总数量;PUBSUB NUMSUB 命令的复杂度为 O ( N ) O(N) O(N),其中 N N N为用户给定的频道数量;PUBSUB NUMPAT命令的复杂度为 O ( 1 ) O(1) O(1)。
版本要求:Redis 2.8.0版本开始可用。
上一篇:Redis学习手册14—持久化