有道无术,术尚可求,有术无道,止于术。
本系列Redis 版本 7.2.5
源码地址:https://gitee.com/pearl-organization/study-redis-demo
1. 概述
Pub/Sub
发布/订阅是一种常见的消息传递模式,消息的发送方将消息发布到某个特定的频道或主题,同时,消息的接收方可以订阅一个或多个频道或主题,以接收并处理发布的消息。
Redis
也支持发布/订阅功能,其机制包括三个部分:
- 发布方(
Publisher
):消息的发送方。将消息发送到特定的频道或主题,不需要知道哪些订阅者正在监听这些消息,发送消息后,通常不会等待订阅方的响应 - 订阅方(
Subscriber
):消息的接收方。可以订阅一个或多个频道或主题,以接收并处理发布的消息。 - 频道(
Channel
):连接发送方和接收方的桥梁,用于传递消息。
客户端可以订阅频道:
当给这个频道发布消息后,消息就会发送给订阅的客户端:
Redis
发布/订阅功能存在很多缺点:
- 消息不能持久化,因此,必须先执行订阅,再等待消息发布。如果没有被订阅,则消息丢弃
- 发布方只管发送消息,不管接收,对于发布者而言消息是即发即失的,也没有
ACK
机制,无法保证消息的消费成功。
在实际应用场景中,并不推荐使用 Redis
的发布/订阅功能。消息队列场景可以使用 Redis Stream
或者专业的MQ
。
2. 常用命令
所有命令:
命名 | 描述 |
---|---|
PSUBSCRIBE | 订阅一个或多个符合给定模式的频道 |
PUBLISH | 将信息发送到指定的频道 |
PUBSUB CHANNELS | 列出当前活动的频道 |
PUBSUB NUMPAT | 返回客户端订阅的唯一模式的数量(这些模式是使用 PSUBSCRIBE 命令订阅的) |
PUBSUB NUMSUB | 返回指定频道的订阅者数量(不包括使用模式订阅的客户端) |
PUBSUB SHARDCHANNELS | 列出当前活动的分片频道 |
PUBSUB SHARDNUMSUB | 返回指定分片频道的订阅者数量 |
PUNSUBSCRIBE | 退订所有给定模式的频道 |
SPUBLISH | 向指定的分片频道发布一条消息 |
SSUBSCRIBE | 将客户端订阅到指定的分片频道 |
SUBSCRIBE | 订阅给定的一个或多个频道的信息 |
SUNSUBSCRIBE | 取消客户端对给定分片频道的订阅,如果没有给出任何频道,则取消对所有分片频道的订阅 |
UNSUBSCRIBE | 指退订给定的频道 |
2.1 PSUBSCRIBE
PSUBSCRIBE
命令用于订阅一个或多个符合给定模式的频道。
基本语法:
PSUBSCRIBE pattern [pattern ...]
pattern
规则:
- 支持
glob
风格的正则表达式。 - 每个模式以
*
作为匹配符,比如it*
匹配所有以it
开头的频道(it.news
、it.blog
、it.tweets
等等) - 特殊字符使用
\
转义。
2.2 PUBLISH
PUBLISH
命令用于将信息发送到指定的频道,返回值为接收到信息 的订阅者数量。
基本语法:
PUBLISH channel message
示例:
# 对没有订阅者的频道发送信息
redis> publish bad_channel "can any body hear me?"
(integer) 0
# 向有一个订阅者的频道发送信息
redis> publish msg "good morning"
(integer) 1
# 向有多个订阅者的频道发送信息
redis> publish chat_room "hello~ everyone"
(integer) 3
2.3 UNSUBSCRIBE
UNSUBSCRIBE
命令用于指示客户端退订给定的频道。
基本语法:
UNSUBSCRIBE [channel [channel ...]]
注意事项:
- 如果没有频道被指定,一个无参数的
UNSUBSCRIBE
调用被执行,那么客户端使用SUBSCRIBE
命令订阅的所有频道都会被退订。在这种情况下,命令会返回一个信息,告知客户端所有被退订的频道。
2.4 SUBSCRIBE
SUBSCRIBE
命令用于订阅给定的一个或多个频道的信息。
基本语法:
SUBSCRIBE channel [channel ...]
3. 应用场景
Redis发布订阅 提供了简单的消息队列功能,但实际应用较少,因为其模式单一、消息丢失性高,但其简单易用,常用于日志等不重要的数据传输。
例如,日志服务订阅频道:
localhost:0>subscribe log-channel
Switch to Pub/Sub mode. Close console tab to stop listen for messages.
1) "subscribe"
2) "log-channel"
3) "1"
开启另外一个控制台,发送信息:
127.0.0.1:6379> publish demo-channel hello
(integer) 1
日志服务会接收到消息:
1) "message"
2) "demo-channel"
3) "hello"