跳转至

52. redis发布订阅及事务

1. 生产消费模型

img_3.png

2. 消息队列的好处

1.松耦合
2.易于扩展

3. 发布订阅实践

#需要至少2个redis窗口,一个发布者,1个或多个订阅者

#1.发布者
publish 频道名 内容
    publish oldguo hi

#2.订阅者
subscribe 频道名
    subscribe oldguo

#注意:若订阅者退出,则发布者发布不了

#3.可以批量订阅
psubscribe old*

#4.可以订阅多个
psubscribe oldboy oldguo
#窗口1 发布者
[root@152 6379]# redis-cli -a 123456
127.0.0.1:6379> publish oldguo hi
(integer) 0

#窗口2 接收者
[root@152 ~]# redis-cli -a 123456
127.0.0.1:6379> subscribe oldguo
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "oldguo"
3) (integer) 1

#窗口1 发送数据
127.0.0.1:6379> publish oldguo hi
(integer) 1
127.0.0.1:6379> publish oldguo hello
(integer) 1

#窗口2 查看
[root@152 ~]# redis-cli -a 123456
127.0.0.1:6379> subscribe oldguo
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "oldguo"
3) (integer) 1
1) "message"
2) "oldguo"
3) "hi"
1) "message"
2) "oldguo"
3) "hello"

#窗口3 订阅多个
[root@152 ~]# redis-cli -a 123456
127.0.0.1:6379> psubscribe oldguo oldchen
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "oldguo"
3) (integer) 1
1) "psubscribe"
2) "oldchen"
3) (integer) 2



#窗口4 批量订阅
[root@152 ~]# redis-cli -a 123456
127.0.0.1:6379> psubscribe old*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "old*"
3) (integer) 1


#窗口1 发布消息,查看窗口3和4
127.0.0.1:6379> publish oldguo hello1
(integer) 3
127.0.0.1:6379> publish oldchen hello2
(integer) 2
127.0.0.1:6379> publish oldcp hello3
(integer) 1

#窗口3 只接受到前2个
[root@152 ~]# redis-cli -a 123456
127.0.0.1:6379> psubscribe oldguo oldchen
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "oldguo"
3) (integer) 1
1) "psubscribe"
2) "oldchen"
3) (integer) 2
1) "pmessage"
2) "oldguo"
3) "oldguo"
4) "hello1"
1) "pmessage"
2) "oldchen"
3) "oldchen"
4) "hello2"

#窗口4 都接受到了
[root@152 ~]# redis-cli -a 123456
127.0.0.1:6379> psubscribe old*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "old*"
3) (integer) 1
1) "pmessage"
2) "old*"
3) "oldguo"
4) "hello1"
1) "pmessage"
2) "old*"
3) "oldchen"
4) "hello2"
1) "pmessage"
2) "old*"
3) "oldcp"
4) "hello3"

4. redis开启、提交事务

multi
set a 1
set b 2
...
exec

#注意:如果事务中有错误命令,则提交失败,所有操作回滚
#redis事务其他操作
discard     #取消事务命令
watch       #监视一个或多个key,如果在事务执行前这些key被其他命令所改动,则事务将被打断
#窗口1 开启事务
[root@152 6379]# redis-cli -a 123456
127.0.0.1:6379> get a1
(nil)
127.0.0.1:6379> get a2
(nil)
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a1 1
QUEUED
127.0.0.1:6379> set a2 2
QUEUED


#窗口2 查看
[root@152 ~]# redis-cli -a 123456
127.0.0.1:6379> get a1
(nil)
127.0.0.1:6379> get a2
(nil)


#窗口1 提交
127.0.0.1:6379> exec
1) OK
2) OK
127.0.0.1:6379> get a1
"1"
127.0.0.1:6379> get a2
"2"


#窗口2 查看
127.0.0.1:6379> get a1
"1"
127.0.0.1:6379> get a2
"2"


#窗口1 再次开启事务并取消
127.0.0.1:6379> get b1
(nil)
127.0.0.1:6379> get b2
(nil)
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set b1 1
QUEUED
127.0.0.1:6379> set b2 2
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get b1
(nil)
127.0.0.1:6379> get b2
(nil)

5. redis事务的锁机制(watch)

#窗口1

watch ticket
multi
set ticket 0
#窗口2
watch ticket
multi
set ticket 1
exec
#窗口1提交事务
exec #将提交失败,因为窗口2中已改动ticket

#此现象成为乐观锁
#演示买票

#窗口1
127.0.0.1:6379> get ticket
(nil)
127.0.0.1:6379> watch ticket
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set ticket 0
QUEUED


#此时,窗口2
127.0.0.1:6379> get ticktet
(nil)
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set ticket 1
QUEUED
127.0.0.1:6379> exec
1) OK
127.0.0.1:6379> get ticket
"1"

#窗口1 提交事务
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get ticket
"1"

#此种现象叫乐观锁

最后更新: 2022-02-20 08:44:07