Redis中的发布订阅和事务

hello,小伙伴们好久不见!前面我们说了redis中的基本数据类型,本文我们来看看redis中的发布订阅和事务,因为这两个都比较简单,因此我放在一篇文章中来讲。

发布订阅

redis的发布订阅系统有点类似于我们生活中的电台,电台可以在某一个频率上发送广播,而我们可以接收任何一个频率的广播,Android中的broadcast也和这类似。

订阅消息的方式如下:

127.0.0.1:6379> SUBSCRIBE c1 c2 c3
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "c1"
3) (integer) 1
1) "subscribe"
2) "c2"
3) (integer) 2
1) "subscribe"
2) "c3"
3) (integer) 3

这个表示接收c1,c2,c3三个频道传来的消息,发送消息的方式如下:

127.0.0.1:6379> PUBLISH c1 "hello redis!"
(integer) 1

当c1这个频道上有消息发出时,此时在消息订阅控制台可以看到如下输出:

1) "message"
2) "c1"
3) "hello redis!"

在redis中,我们也可以使用模式匹配订阅,如下:

127.0.0.1:6379> PSUBSCRIBE c*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "c*"
3) (integer) 1

此时可以接收到所有以c开头的频道发来的消息。

tips

redis中的发布订阅系统在某些场景下还是非常好用的,但是也有一些问题需要注意:由于网络在传输过程中可能会遭遇断线等意外情况,断线后需要进行重连,然而这会导致断线期间的数据丢失。

事务

既然redis是一种NoSQL数据库,那它当然也有事务的功能,不过这里的事务和我们关系型数据库中的事务有一点点差异。 redis中事务的用法非常简单,我们通过MULTI命令开启一个事务,如下:

127.0.0.1:6379> MULTI
OK

在MULTI命令执行之后,我们可以继续发送命令去执行,此时的命令不会被立马执行,而是放在一个队列中,如下:

127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED

当所有的命令都输入完成后,我们可以通过EXEC命令发起执行,也可以通过DISCARD命令清空队列,如下:

127.0.0.1:6379> EXEC
1) OK
2) OK
3) OK

事务中的异常情况

redis中事务的异常情况总的来说分为两类: 1.进入队列之前就能发现的错误,比如命令输错; 2.执行EXEC之后才能发现的错误,比如给一个非数字字符加1;

那么对于这两种不同的异常,redis中有不同的处理策略。对于第一种错误,服务器会对命令入队失败的情况进行记录,并在客户端调用 EXEC 命令时,拒绝执行并自动放弃这个事务(这个是2.6.5之后的版本做法,之前的版本做法小伙伴可以参考官方文档)。如下:

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set kv1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3 3 3
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
3) (error) ERR syntax error
4) OK
127.0.0.1:6379> keys *
1) "k4"
2) "k2"
3) "kv1"

而对于第二种情况,redis并没有对它们进行特别处理, 即使事务中有某个/某些命令在执行时产生了错误, 事务中的其他命令仍然会继续执行。如下:

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 vv
QUEUED
127.0.0.1:6379> INCR k1
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (error) ERR value is not an integer or out of range
127.0.0.1:6379> GET k1
"vv"

不同于关系型数据库,redis中的事务出错时没有回滚,对此,官方的解释如下:

Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

WATCH命令

事务中的WATCH命令可以用来监控一个key,通过这种监控,我们可以为redis事务提供(CAS)行为。 如果有至少一个被WATCH监视的键在EXEC执行之前被修改了,那么整个事务都会被取消,EXEC返回nil-reply来表示事务已经失败。如下:

通过unwatch命令,可以取消对一个key的监控,如下:

OK,发布订阅和事务我们就介绍这么多,更多命令小伙伴们可以参考官方文档http://www.redis.cn/commands.html。小伙伴在看官方文档时,有什么问题欢迎留言讨论。

原文发布于微信公众号 - 牧码小子(gh_d1ca11234a30)

原文发表时间:2018-05-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏黑白安全

CVE-2018-5767路由器远程代码执行分析

参考信息:https://www.fidusinfosec.com/remote-code-execution-cve-2018-5767/

1634
来自专栏云计算教程系列

Django入门:搭建你第一个应用

Django是用Python编写的免费开源Web框架,用了MVC的框架模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内...

1622
来自专栏IT笔记

Spring Quartz任务案例源码实现

写在开始 上一篇有讲到 springTask任务案例源码实现 此篇,spring整合Quartz实现更强大的定时任务。 任务介绍 Quartz存储job方式就...

2894
来自专栏Java帮帮-微信公众号-技术文章全总结

Quartz调度源码分析【面试+工作】

Quartz内部提供的调度类是QuartzScheduler,而QuartzScheduler会委托QuartzSchedulerThread去实时调度;当调度...

1112
来自专栏白驹过隙

SCons - 简单而强大的项目编译脚本

48410
来自专栏bluesummer

StackExchange.Redis学习笔记(四) 事务控制和Batch批量操作

Redis事物 Redis命令实现事务 Redis的事物包含在multi和exec(执行)或者discard(回滚)命令中 和sql事务不同的是,Redis调用...

32912
来自专栏Albert陈凯

Zookeeper安装部署调试命令

下载地址: http://www.apache.org/dyn/closer.cgi/zookeeper/ 我选用清华的镜像 https://mirrors...

2965
来自专栏技术小讲堂

ASP.NET AJAX(11)__ScriptManagerUpdatePanel的支持成员功能控制成员脚本控件支持成员ScriptMode和ScriptPathLoadScriptsBeforeU

ScriptManager的作用,这个不言而喻,它是整个的ASP.NET AJAX的核心 UpdatePanel的支持成员 static void Regist...

3106
来自专栏DOTNET

MongoDB模拟多文档事务操作

Mongodb不支持多文档原子性操作,因此依据两阶段提交协议(Two Phase Commits protocol)来模拟事务。 以两个银行账户之间的转账行为为...

4979
来自专栏北京马哥教育

10 分钟快速搭建 ELK 日志分析系统

作者:Json、 一、ELK搭建篇 官网地址: https://www.elastic.co/cn/ 官网权威指南: https://www.elastic....

2.6K10

扫码关注云+社区

领取腾讯云代金券