Redis学习笔记(2)-发布与订阅

发布于:2022-12-10 ⋅ 阅读:(592) ⋅ 点赞:(0)

ps:这是我的学习笔记网站:TinkerBell学习笔记

Redis发布与订阅

什么是发布订阅

Redis 发布订阅( pub/sub )是一种消息通信模式:发送者( pub )发送消息,订阅者( sub )接收消息。

Redis 客户端可以订阅任意数量的频道。

redis发布于订阅

发布者可以建立许多个频道进行消息的发送(如上图频道1、频道2、频道3),供订阅者进行接收和监听消息。

1.客户端可以订阅频道,例如channel1频道

订阅

2.当发布者给这个频道发布消息后,消息就会发送给订阅的客户端

发布与订阅

通俗的解读一下:1.发送者建立频道,2.订阅者去订阅这个频道,3.发布者往频道发送了消息,4.所有订阅频道的订阅者都会收到消息

为什么要用发布订阅

  • 对比中间件,针对消息订阅发布功能,市面上很多大多使用的是kafka、RabbitMQ、ActiveMQ, RocketMQ等这几种,redis的订阅发布功能跟这三者相比,相对轻量,针对数据准确和安全性要求没有那么高可以直接使用,适用于小型项目。

  • redis 的List数据类型结构提供了 blpop 、brpop 命令结合 rpush、lpush 命令可以实现消息队列机制,基于双端链表实现的发布与订阅功能

这种方式存在两个局限性:

  • 不能支持一对多的消息分发。
  • 如果生产者生成的速度远远大于消费者消费的速度,易堆积大量未消费的消息

发布/订阅如何使用

Redis有两种发布/订阅模式:

  • 基于频道(Channel)的发布/订阅
  • 基于模式(pattern)的发布/订阅

基于频道

序号 命令与描述
subscribe channel [channel … ] 订阅给定的一个或多个频道
unsubscribe channel [channel … ] 退订给定的频道 (说明:若没有指定channel,则默认退订所有频道)
publish channel message 将消息发送给指定频道 channel (返回结果:接收到信息的订阅者数量,无订阅者返回0)
pubsub channels [argument [atgument …] ] 查看订阅与发布系统的状态 说明:返回活跃频道列表(即至少有一个订阅者的频道,订阅模式的客户端除外)
  • 订阅者订阅频道 subscribe channel [channel …]
-------------客户端1(订阅者) :订阅频道 ---------------------
 
# 订阅 “tinker” 和 “csdn” 频道(如果不存在则会创建频道)
127.0.0.1:6379> subscribe tinker csdn 
Reading messages... (press Ctrl-C to quit)
 
1) "subscribe"    -- 返回值类型:表示订阅成功!
2) "tinker" -- 订阅频道的名称
3) (integer) 1    -- 当前客户端已订阅频道的数量
 
1) "subscribe"
2) "csdn"
3) (integer) 2
 
#注意:订阅后,该客户端会一直监听消息,如果发送者有消息发给频道,这里会立刻接收到消息
  • 发布者发布消息 publish channel message
-------------客户端2(发布者):发布消息给频道 ---------------
 
 
# 给“tinker”这个频道 发送一条消息:“I am tinker”
127.0.0.1:6379> publish tinker "I am tinker"
(integer) 1  # 接收到信息的订阅者数量,无订阅者返回0
 
  • 客户端2 (发布者) 发布消息给频道后,此时我们再来观察 客户端1 (订阅者) 的客户端窗口变化:
 ---------变化如下:(实时接收到了该频道的发布者的消息)------
 
1) "message"           -- 返回值类型:消息
2) "tinker"      -- 来源(从哪个频道发过来的)
3) "I am tinker" -- 消息内容

底层原理

底层通过字典实现。pubsub_channels 是一个字典类型,保存订阅频道的信息:字典的key为订阅的频道, 字典的value是一个链表, 链表中保存了所有订阅该频道的客户端

频道模式底层原理图

分析

频道订阅:订阅频道时先检查字段内部是否存在;不存在则为当前频道创建一个字典且创建一个链表存储客户端id;否则直接将客户端id插入到链表中。

取消频道订阅:取消时将客户端id从对应的链表中删除;如果删除之后链表已经是空链表了,则将会把这个频道从字典中删除。

发布:首先根据 channel 定位到字典的键, 然后将信息发送给字典值链表中的所有客户端

基于模式

如果有某个/某些模式和该频道匹配,所有订阅这个/这些频道的客户端也同样会收到信息。

序号 命令与描述
psubscribe pattern1 [pattern…] 订阅一个或多个符合给定模式的频道 说明:每个模式以 * 作为匹配符;例如 cn* 匹配所有以cn开头的频道:cn.java、cn.csdn
punsubscribe [pattern [pattern …] ] 退订所有给定模式的频道 说明:pattern 未指定,则订阅的所有模式都会被退订,否则只退订指定的订阅的模式

基于模式

分析

简单解释一下:这里的模式跟RabbitMQ的topic模式相似,采用*来做通配符,*表示任何一个词,只要能匹配上就会接收到消息

通配符中?表示1个占位符,*表示任意个占位符(包括0),?*表示1个以上占位符。

ps:这是我的学习笔记网站:TinkerBell学习笔记

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到