一.事务概念
1.先说概念,什么是事务
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作。
也就是说Redis的事务其实就是假事务,当事务中多个指令同时进行时,有一个指令执行失败了,并不会影响其他指令的执行,已经执行的指令不会回滚,还没有执行的指令还是会继续往下执行。
2.Redis中事务是如何执行的
2.1.Redis 事务可以一次执行多个命令, 并且可以保证以下三点
(1).批量操作在发送 EXEC 命令前被放入队列缓存。
(2).收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
(3).在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
2.2.一个事务从开始到执行会经历以下三个阶段:
(1).开启事务
(2).命令会按序排入一个队列
(3).执行事务
3.事务的原理
当执行
multi
命令将会开启事务,那么所有命令就会加入事务队列缓存起来,不会真正的直接执行,如果遇到exec
就会把队列中的命令依次执行-提交事务,即使有命令执行失败了,也不会影响其他命令的执行结果并且不会数据回滚,如果遇到discard就会放弃执行队列中的命令-取消事务
如图
2.操作事务
2.1.开启事务multi
multi #开启事务
set age0 18
set age1 19
incr age0 #age0对应的value自增一
decr age1 #age1对应的value自减一
2.2.执行事务exec
执行所有事务队列中的全部命令
exec #提交事务,开启事务 (multi) 后的所有命令将被执行
2.3.取消事务discard
取消事务并丢弃队列中的所有指令
discard #取消事务,开启multi后的所有命令将被丢弃
二.发布及订阅
1.照旧先说概念,什么是发布和订阅
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。Redis服务器可以发送消息给任意数量的频道,客户端可以订阅任意数量的频道。(pub/sub)是一种fanout广播模式,可以把消息发送给所有的订阅者
2.发布、订阅的原理
消息接受者通过
SUBSCRIBE channel
命令订阅某个频道 , 消息发布者通过PUBLISH channel message
向该频道发布消息,那么订阅了该频道的所有接受者就可以收到消息。
如图
3.发布订阅的操作
3.1.发布消息
PUBLISH channel message #向通道channel中发送消息message
PUBLISH vic0 helloworld0 #向名为vic0的通道中发送消息helloworld0
PUBLISH vic1 helloworld1 #向名为vic1的通道中发送消息helloworld1
PUBLISH vic1 helloworld2 #向名为vic1的通道中发送消息helloworld2
3.2.订阅消息
SUBSCRIBE channle #订阅名为channle的频道
SUBSCRIBE vic0 #订阅名为vic0的频道
SUBSCRIBE vic1 #订阅名为vic1的频道
SUBSCRIBE vic0 vic1 #同时订阅名为vic0和vic1的频道
多个客户端链接同一个服务器之后,任意一个客户端向服务的通道中发送消息,都可以被任何订阅了该通道的任意客户端接收到。
如图
开启了三个客户端,因为我是本地连接所以不需要-h -p默认就是连接本机,用客户端1和客户端2同时监听vic0通道时,当用客户端3向该通道发送消息后,客户端1和2同时接收到客户端3发送的消息。
4. 发布订阅的缺点
那么有朋友就问了,Redis这么好用,还要MQ干嘛呢,Redis这做的不就是消息队列的活吗。是这样的,但是他的局限性也不得不让我们引入一些其他的比较重的消息队列机制。
比如:
消息生产者生产一条消息,Redis 会直接找到相应的消费者发送过去。如果一个消费者都没有,那么消息会被直接丢弃。
如果开始有多消费者,其中一个宕机了,生产者发送消息,其他的消费者可以持续收到消息。但是宕机的消费者重新连接之后,中间这个消费者错过的这些消息是无法恢复的。也就是说如果 Redis 重启,消息是不会持久化的,所有的消息直接被丢弃,就会造成队列消息丢失的情况。
今天就先到这里吧,因为五一放假所以这篇断断续续写了有两三天思路可能不是很连贯了已经,祝大家劳动节快乐,下面几期会跟大家聊聊持久化策略和淘汰策略的操作,以及我们的代码中该如何操作Redis。还望各位看官点个赞再走吧,给您劈个叉~白白