Redis基础知识(学习笔记14--发布/订阅)

一. 发布/订阅命令

1.1 消息系统

发布/订阅,即pub/sub,是一种消息通信模式:发布者也称消息生产者,生产和发送消息到存储系统;订阅者也称为消息消费者,从存储系统接受和消费消息。这个存储系统可以是文件系统FS、消息中间件MQ、数据管理系统DBMS,也可以是Redis。整个消息发布者、订阅者与存储系统统称为消息系统。

消息系统中的订阅者订阅了某类消息后,只要存储系统中存在该类消息,其就可不断的接受并消费这些消息。当存储系统中没有该消息后,订阅者的接受、消费阻塞。而当发布者将消息写入到存储系统后,会立即唤醒订阅者。当存储系统放满时,不同的发布者具有不同的处理方式:有的会阻塞发布者的发布,等待可用的存储空间;有的则会将多余的消息丢失。

当然,不同的消息系统消息的发布/订阅方式也是不同的。例如RocketMQ、Kafka等消息中间件构成的消息系统中,发布/订阅的消息都是以Topic分类的。而Reids构成的消息系统中,发布/订阅的消息都是以频道Channel分类的。

 1.2 subscibe

SUBSCRIBE channel [channel ...]

redis客户端通过一个subscibe命令可以同时订阅任意数量的频道。在输出了订阅了主题后,命令处于阻塞状态,等待相关频道的消息。

1.3 pubsubscibe

PSUBSCRIBE pattern [pattern ...]

订阅一个或多个符合给定模式的频道。

说明:这里的模式只能使用通配符*。例如,it*可以匹配所有以it开头的频道,像it.news、it.blog、it.tweets等;news.*可以匹配所有以news.开头的频道,像news.global.today、news.it等。

1.4 publish

PUBLISH channel message

reids 客户端将信息 message 发送到指定的频道 channel 。返回值:接收到信息 message 的订阅者数量。

1.5 unsubscibe

UNSUBSCRIBE [channel [channel ...]]

redis客户端退订给定的频道。

说明:如果没有频道被指定,也即是,一个无参数的 UNSUBSCRIBE 调用被执行,那么客户端使用 SUBSCRIBE 命令订阅的所有频道都会被退订。在这种情况下,命令会返回一个信息,告知客户端所有被退订的频道。

1.6 punsubscibe

PUNSUBSCRIBE [pattern [pattern ...]]

退订一个或多个符合给定模式的频道。

说明:这里的模式只能使用通配符*。如果没有模式被指定,也即是,一个无参数的 PUNSUBSCRIBE 调用被执行,那么客户端使用 PSUBSCRIBE 命令订阅的所有模式都会被退订。在这种情况下,命令会返回一个信息,告知客户端所有被退订的模式。

1.7 pubsub

PUBSUB <subcommand> [argument [argument ...]]

PUBSUB 是一个查看订阅与发布系统状态的内省命令, 它由数个不同格式的子命令组成, 以下将分别对这些子命令进行介绍。

(1)PUBSUB CHANNELS

PUBSUB CHANNELS [pattern]

列出当前的活跃频道(活跃的意思是有订阅者的意思)。活跃频道指的是那些至少有一个订阅者的频道, 订阅模式的客户端不计算在内。

说明:pattern 参数是可选的。如果不给出 pattern 参数,那么列出订阅/发布系统中的所有活跃频道。如果给出 pattern 参数,那么只列出和给定模式 pattern 相匹配的那些活跃频道。pattern中只能使用通配符*。

(2)PUBSUB NUMSUB

PUBSUB NUMSUB [channel-1 ... channel-N]

返回给定频道的订阅者数量, 订阅模式的客户端不计算在内。不给定任何频道,命令只返回一个空列表。

(3)PUBSUB NUMPAT

PUBSUB NUMPAT

返回订阅模式的数量,所有客户端订阅的所有频道模式的数量总和。 注意, 这个命令返回的不是订阅模式的客户端的数量, 而是客户端订阅的所有模式的数量总和。返回值为 一个整数回复(Integer reply)。

二. Redis 事务

Redis的事务的本质是一组命令的批处理。这组命令在执行过程中会被顺序地、一次性全部执行完毕,只要没有出现语法错误,这组命令在执行期间是不会被中断的。

2.1 Redis事务特性

Redis的事务仅保证了数据的一致性,不具有像DBMS一样的ACID特性。

*** 这组命令中的某些命令的执行失败不会影响其它命令的执行,不会引发回滚。即不具备原子性。

*** 这组命令通过乐观锁机制实现了简单的隔离性。没有复杂的隔离级别。

*** 这组命令的执行结果是被写入到内存的,是否持久取决于Redis的持久化策略,与事务无关。

2.2 Redis事务实现

(1)三个命令

Redis事务通过三个命令进行控制。

*** muti:开启事务。

*** exec:执行事务。

*** discard:取消事务。

(2)基本使用

下面是定义并执行事务的用法

MULTI

MULTI

标记一个事务块的开始。事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。返回值,总是返回 OK 。

EXEC

EXEC

执行所有事务块内的命令。假如某个(或某些) key 正处于 WATCH 命令的监视之下,且事务块中有和这个(或这些) key 相关的命令,那么 EXEC 命令只在这个(或这些) key 没有被其他命令所改动的情况下执行并生效,否则该事务被打断(abort)。返回值:事务块内所有命令的返回值,按命令执行的先后顺序排列;当操作被打断时,返回空值 nil 。

DISCARD

DISCARD

取消事务,放弃执行事务块内的所有命令。如果正在使用 WATCH 命令监视某个(或某些) key,那么取消所有监视,等同于执行命令 UNWATCH 。返回值总是返回 OK 。

WATCH

WATCH key [key ...]

监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。返回值:总是返回 OK 。

这种又称为 Reids的乐观锁,其实现原理依赖是数据记录的版本号。

UNWATCH

UNWATCH

取消 WATCH 命令对所有 key 的监视。如果在执行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被执行了的话,那么就不需要再执行 UNWATCH 了。因为 EXEC 命令会执行事务,因此 WATCH 命令的效果已经产生了;而 DISCARD 命令在取消事务的同时也会取消所有对 key 的监视,因此这两个命令执行之后,就没有必要执行 UNWATCH 了。

(3)案例

# 事务被成功执行

redis> MULTI
OK

redis> INCR user_id
QUEUED

redis> INCR user_id
QUEUED

redis> INCR user_id
QUEUED

redis> PING
QUEUED

redis> EXEC
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG


# 监视 key ,且事务成功执行

redis> WATCH lock lock_times
OK

redis> MULTI
OK

redis> SET lock "huangz"
QUEUED

redis> INCR lock_times
QUEUED

redis> EXEC
1) OK
2) (integer) 1


# 监视 key ,且事务被打断

redis> WATCH lock lock_times
OK

redis> MULTI
OK

redis> SET lock "joe"        # 就在这时,另一个客户端修改了 lock_times 的值
QUEUED

redis> INCR lock_times
QUEUED

redis> EXEC                  # 因为 lock_times 被修改, joe 的事务执行失败
(nil)

 

学习参阅声明

1.【Redis视频从入门到高级】

https://www.bilibili.com/video/BV1U24y1y7jF?p=11&vd_source=0e347fbc6c2b049143afaa5a15abfc1c】

2. 【Redis 命令参考】

https://haiyong.site/doc/redis/redis-gh-pages/hash/hscan.html

热门相关:信息全知者   巨星小甜妻:前夫,请出局   我真不是开玩笑   新书   秦吏