Redis事务
Redis事务可以一次执行多个命令,并且带哟以下三个重要的保证
- 批量操作在发送EXEC命令前被放入队列缓存
- 收到EXEC命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中
一个事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
实例
以下是一个事务的例子,它先以MULTI开始一个事务,然后将多个命令入队到事务中,最后由EXEC命令触发事务,一并执行事务中的所有命令:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET book-name "Mastering C++ in 21days"
QUEUED
127.0.0.1:6379> GET book-name
QUEUED
127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED
127.0.0.1:6379> SMEMBERS tag
QUEUED
127.0.0.1:6379> EXEC
OK
Mastering C++ in 21days
3
Mastering Series
C++
Programming
127.0.0.1:6379>
单个Redis命令的执行是原子性的,但Redis没有在事务上增加任何维持原子性的机制,所以Redis事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行的脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
这是官网上的说明From redis docs on transactions:
It’s important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands.
翻译:值得注意的是,即使一个命令失败了,队列中的所有其他命令都被处理了——Redis不会停止对命令的处理。
例如:
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a aaa
QUEUED
127.0.0.1:6379> set b bbb
QUEUED
127.0.0.1:6379> set c ccc
QUEUED
127.0.0.1:6379> exec
OK
OK
OK
127.0.0.1:6379>
如果在set b bbb处失败,set a已成功不会回滚,set c还会继续执行
Redis事务命令
| 序号 | 命令及描述 |
|---|---|
| 1 | DISCARD取消事务,放弃执行事务块内的所有命令 |
| 2 | EXEC执行所有事务块内的命令 |
| 3 | MULTI标记一个事务块的开始 |
| 4 | UNWATCH取消WATCH命令对所有key的监视 |
| 5 | WATCH key [key...]监视一个(或多个)key,如果在事务执行前这个(或这些)key被其他命令所改动,那么事务将被打断。 |
Redis持久化
Redis是内存数据库,如果不将内存中的数据保存到磁盘中,那么一旦服务器进程推出,服务器中的数据库状态也会消失,所以Redis提供了持久化的功能。
Redis有两种持久化方式:RDB和AOF
RDB(Redis DataBase)快照方式
当符合一定条件时,Redis会自动将内存中所有的数据生成一份副本并存储在硬盘中,这个过程被称为“快照”。
Redis会有4中情况对数据进行快照:
- 根据配置规则进行自动快照
- 用户执行SAVE或BGSAVE命令
- 执行FLUSHALL命令
- 执行复制(replication)时。

Redis会单独创建(fork)一个子进程来持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上一次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进程大规模数据的恢复,且对数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
优点
- 1适合大规模的数据恢复
- 2对数据的完整性要求不高
缺点 - 1需要一定的时间间隔进行操作,如果redis意外宕机,最后一次持久化的操作数据就没有了
- 2fork进程的时候,会需要占用一定的内存空间
AOF(Append Only File)日志形式
通过RDB方式实现持久化,一旦Redis异常推出,就会丢失最后一次快照之后更改的所有数据。为了降低因进程中止导致的数据丢失风险,可以使用AOF方式实现数据持久化。
AOF持久化是以日志的形式记录服务器的每一个写、删除操作,查询操作不会记录,以文本的方式记录,文件中可以看到详细的操作记录。
Redis重启会根据日志文件的内容将指令从前到后执行一次以完成数据的恢复工作
默认情况下,Redis没有开启AOF方式的持久化,可以通过appendonly参数启动:appendonly yes
开启AOF持久化后,每执行一条会更改Redis中数据的命令,Redis就会将该命令写入硬盘中的AOF格式的文件,即.aof格式文件存储的是一些redis指令。
优点
- 1每一次修改都同步,文件的完整性比较好
- 2每秒同步一次,可能会丢失1s的数据
缺点
- 1相对于数据文件来说,aof远远大于rdb
- 2修复的速度比rdb慢
- 3AOF的运行效率也比rdb慢
Redis发布订阅
Redis发布订阅(pub/sub)是一种消息通信模式:发布者(pub)发送消息,订阅者(sub)接收消息。
Redis客户端可以订阅任意数量的频道。
发布订阅模型

下图展示了频道channel1,以及订阅这个频道的三个客户端,client2、client5、client1之间的关系。

当有新消息通过PUBLISH命令发送给channel1时,这个消息就会被发送给订阅它的三个客户端:

实例
我们开启两个客户端,在实例中创建订阅频道名为runoobChat
第一个客户端:
127.0.0.1:6379> SUBSCRIBE runoobChat
subscribe
runoobChat
1
现在打开第二个客户端,然后在同一频道runoobChat发布两次消息,订阅者就能接收到消息
第二个客户端
127.0.0.1:6379> PUBLISH runoobChat "Redis PUBLISH test"
1
127.0.0.1:6379> PUBLISH runoobChat "Learn redis by runoob.com"
1
127.0.0.1:6379>
订阅者的客户端就会显示如下消息
message
runoobChat
Redis PUBLISH test
message
runoobChat
Learn redis by runoob.com
动图展示:


Redis发布订阅命令
| 序号 | 命令及描述 |
|---|---|
| 1 | PSUBSCRIBE pattern [pattern...]订阅一个或多个符合给定模式的频道 |
| 2 | PUBSUB subcommand [argument [argument...]]查看订阅与发布系统的状态 |
| 3 | PUBLISH channel message将信息发送到指定的频道 |
| 4 | PUNSUBSCRIBE [pattren [pattren...]]退订所有给定模式的频道 |
| 5 | SUBSCRIBE channel [channel]订阅给定的一个或多个频道的信息 |
| 6 | UNSUBSCRIBE [channel [channel...]]指退订给定的频道 |
原理
Redis是使用C实现的,通过分析Redis源码里的pubsub.c文件,了解发布和订阅机制的底层实现,借此加深对Redis的理解。
Redis通过PUBLISH、SUBSCRIBE和PSUBSCRIBE等命令实现发布和订阅功能。
通过SUBSCRIBE命令订阅某频道后,redis-server里维护一个字典,字典的键就是一个个channel,而字典的值则是一个链表,链表中保存了所有订阅这个channel的客户端。SUBSCRIBE命令的关键,就是将客户端添加到给定channel的订阅链表中。
通过PUBLISH命令向订阅者发送消息,redis-server会使用给定的频道作为键,在它所维护的
channel字典中查找记录了订阅这个频道的所有客户端的链表,遍历这个链表,将消息发布给所有订阅者。
Pub/Sub从字面上理解就是发布(Publist)与订阅(Subscribe),在Redis中,可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅他的客户端都会受到相应的消息。这一功能最明显的用法就是用作实时消息系统,比如普通的即时聊天,群聊等功能。
适用场景
- 1实时消息系统
- 2实时聊天,频道当作聊天室,将信息回显给所有人即可
- 3订阅,关注系统都是可以的
本文介绍了Redis事务的基础知识,包括其执行流程与特性,并详细解释了两种持久化方式:RDB快照方式与AOF日志形式。同时,还探讨了Redis的发布订阅功能及其应用场景。
909

被折叠的 条评论
为什么被折叠?



