Redis事务的分析及改进
Redis的事务特性
数据ACID特性满足了几条?
为了保持简单,redis事务保证了其中的一致性和隔离性;
不满足原子性和持久性;
原子性
redis事务在执行的中途遇到错误,不会回滚,而是继续执行后续命令;(违反原子性)
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作;
中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做;
比如:
redis 127.0.0.1:7000> multi
OK
redis 127.0.0.1:7000>set a aaa
QUEUED
redis 127.0.0.1:7000>set b bbb
QUEUED
redis 127.0.0.1:7000>set c ccc
QUEUED
redis 127.0.0.1:7000>exec1) OK
2) OK
3) OK
如果在set b bbb处失败,set a已成功不会回滚,set c还会继续执行;
持久性
事务不过是用队列包裹起了一组 Redis 命令,并没有提供任何额外的持久性功能,所以事务的持久性由 Redis 所使用的持久化模式决定:
- 在单纯的内存模式下,事务肯定是不持久的。
- 在 RDB 模式下,服务器可能在事务执行之后、RDB 文件更新之前的这段时间失败,所以 RDB 模式下的 Redis 事务也是不持久的。
- 在 AOF 的“总是 SYNC ”模式下,事务的每条命令在执行成功之后,都会立即调用 fsync 或 fdatasync 将事务数据写入到 AOF 文件。但是,这种保存是由后台线程进行的,主线程不会阻塞直到保存成功,所以从命令执行成功到数据保存到硬盘之间,还是有一段非常小的间隔,所以这种模式 下的事务也是不持久的。
- 其他 AOF 模式也和“总是 SYNC ”模式类似,所以它们都是不持久的。
隔离性和一致性
redis事务在执行的过程中,不会处理其它命令,而是等所有命令都执行完后,再处理其它命令(满足隔离性)
redis事务在执行过程中发生错误或进程被终结,都能保证数据的一致性;(详见参考资料1)
redis事务的缺陷
除了不保证原子性和持久性,在实际使用中还有以下问题:
1) 遇到有查询的情况穿插在事务中间,不会返回结果;
设置事务开始标志后,所有的命令都是queued,即使是查询指令;
如果后续的更新操作需要依赖于前面的查询指令,那redis事务就无法有效的完成任务;
例如:
redis 127.0.0.1:7000> multi
OK
redis 127.0.0.1:7000>set a aaa
QUEUED
redis 127.0.0.1:7000>get b
QUEUED
业务逻辑...
redis 127.0.0.1:7000>set c ccc
QUEUED
redis 127.0.0.1:7000>exec1) OK
2) bbb
3) OK
第二步 get a 返回的是queued,并不是a的查询结果,
如果后续的set操作依赖于get的结果(存在依赖业务逻辑),就不能将get操作放在事务操作中;
2) 事务中的每条命令都与redis服务器进行了一次网络交互;
redis 事务指定开始后,执行一个事务返回的都是queued,那这个入队操作是在客户端实现,还是在服务器端实现的?
查看源码,很容易发现是在服务器端实现;
在Redis.c中有这么一段:
int processCommand(redisClient *c){.../* Exec the command */if(c->flags & REDIS_MULTI &&
c->cmd->proc != execCommand && c->cmd->proc != discardCommand &&
c->cmd->proc != multiCommand && c->cmd->proc != watchCommand){
queueMultiCommand(c);// 将事务中的命令都放入到队列中,然后返回"QUEUED"
addReply(c,shared.queued);}else{if(server.vm_enabled && server.vm_max_threads >0&&
blockClientOnSwappedKeys(c))return REDIS_ERR;//调用该命令函数来处理命令
call(c);}return REDIS_OK;}
这里就涉及到客户端与服务器端的多次交互,明明是需要一次批量执行的n条命令,还需要通过多次网络交互,有些浪费;
更新操作中的查询实现
如果有这样的需求:在事务开始后,中间穿插有查询逻辑;
那么使用redis事务(单库),无法满足这个要求;
可能的解决方案:
-
可以考虑使用多个库,读写分离,查询库只用来查询,更新库用来开事务做写操作;
-
不再使用redis的事务指令,自己在客户端将待执行的命令批量打包,决定是否回滚还是全部执行;这样可以在更新的间隙执行查询逻辑;而不需要将查询逻辑提前到事务指令multi之前;
-
将查询业务逻辑提前;严格规范代码编写要求,所有的redis查询逻辑都放在事务之外:
redis 127.0.0.1:7000>get b bbb 业务逻辑... redis 127.0.0.1:7000> multi OK redis 127.0.0.1:7000>set a aaa QUEUED redis 127.0.0.1:7000>set c ccc QUEUED redis 127.0.0.1:7000>exec1) OK 2) OK
优化网络特性
将多个命令打包批量发送到redis服务器执行,减少网络交互,优化性能,可能的解决方案:
- 对于所有的get/set操作,可使用现有的mget/mset指令;
- 对于各种不同类型的更新操作,可使用lua脚本将命令打包后,发送到服务器端一次执行;
参考
http://redisbook.readthedocs.org/en/latest/feature/transaction.html
http://www.cnblogs.com/me115/p/4326375.html
相关推荐
Redis是一款高性能的键值对数据库,它以C语言编写,支持网络,是完全开源的,拥有丰富的数据结构,如字符串、哈希、列表、集合、有序集合等,同时还提供了发布/订阅、事务、持久化、主从复制等功能,广泛应用于缓存...
6. 事务管理:支持Redis事务的执行和查看,确保操作的原子性。 7. 备份与恢复:方便地备份Redis数据,并在需要时进行恢复。 8. 配置管理:查看和修改Redis服务器的配置参数,优化性能。 总的来说,这款Redis视图化...
在3.2版本中,Redis引入了一些关键特性,同时也进行了一系列的优化和改进,使得其在Windows平台上的性能更加稳定和高效。 1. 安装过程:Redis-x64-3.2.100.msi是Windows Installer包,通过双击运行可以引导用户进行...
对于学习和研究Redis,特别是进行毕业设计或计算机案例分析的人员,了解和分析Redis源码可以帮助深入理解数据库的内部工作原理,提升系统设计和优化的能力。同时,通过源码学习,也可以为自定义Redis插件或扩展提供...
Redis 6.0.16 版本带来了许多改进和新特性: 1. **多线程支持**:Redis 6 引入了多线程模式,通过后台线程处理网络 I/O,提高了处理大量并发连接的能力,从而提升了性能。这使得 Redis 在高并发场景下表现更优。 2...
Redis 5.0.5是Redis的一个稳定版本,带来了多项改进和优化。以下将详细介绍Redis及其5.0.5版本在Windows下的安装与使用、主要特性以及相关配置知识。 1. **安装与运行** - 解压"redis-5.0.5.zip"至任意目录,如"C:...
此外,Redis还支持事务(Transactions)、发布/订阅(Publish/Subscribe)模式以及 Lua 脚本执行,进一步增强了其功能。 免编译版本意味着用户可以直接在操作系统上运行,无需关心编译环境和依赖项。这通常包括所有...
4. **事务支持**:Spring Data Redis允许开发者使用`RedisTransactionManager`来管理Redis的事务,提供了与传统关系型数据库相似的事务操作能力,如BEGIN、COMMIT、ROLLBACK等。 5. **持久化策略**:Spring Data ...
例如,最初的版本可能仅支持基本的数据操作,而随着版本的迭代,Redis添加了事务(Transactions)、发布/订阅(Publish/Subscribe)功能,以及主从复制(Replication)。在性能方面,Redis不断优化其命令处理速度和...
3. **事务**: Redis支持事务,允许一次性执行多个操作,保证了操作的原子性。 4. **发布/订阅**: Redis提供消息发布与订阅功能,用于实现简单的消息传递和实时通信。 5. **主从复制**: Redis支持主从复制,可以创建...
1. AOF持久化改进:Redis 6.2.4增强了Append Only File (AOF) 持久化策略,提供了更高效的重写机制,减少了磁盘占用。 2. Lua脚本增强:支持更多内建函数,如`random`和`sha1hex`,使得Lua脚本功能更加强大。 3. ...
4. **事务**: Redis支持简单事务,允许用户一次性执行多个操作,确保原子性。 5. **Lua脚本**: Redis 2.4引入了Lua脚本功能,允许用户编写简单的脚本并在服务器端执行,提高处理复杂操作的效率。 **Redis 2.6.8** ...
5. **事务**:Redis支持简单的事务机制,允许一次执行多个操作,确保原子性。 6. **发布/订阅**:Redis的发布订阅(Pub/Sub)模式使得可以构建实时的消息系统,让多个客户端可以订阅同一主题并接收消息。 7. **Lua...
3. **事务改进**:尽管Redis不支持ACID事务,但6.0.7对事务执行效率进行了优化,提升了并发性能。 4. **多线程**:Redis 6 引入了IO多线程,提高了网络I/O性能,但命令执行仍保持单线程,以维护简单性和一致性。 5. ...
Redis支持事务,可以批量执行命令,保证命令的原子性。使用`MULTI`、`EXEC`命令来开启和结束一个事务。 4. **发布/订阅(Publish/Subscribe)**: Redis允许通过频道进行消息的发布与订阅,实现简单的消息传递。 5...
4. **事务支持**:Redis 支持原子的多操作事务,确保一系列操作要么全部成功,要么全部失败。 5. **主从复制**:Redis 可以设置为主从模式,实现数据备份和负载均衡。主节点负责写操作,从节点负责读操作,提高了...
Redis 6.0.8是Redis的一个稳定版本,它包含了自Redis 6.0.0发布以来的一系列更新和改进,旨在增强性能、安全性和功能。对于32位Windows用户来说,这是一个重要的发布,因为通常Redis主要针对64位系统优化,而此版本...
Redis 3.2 是一个重要的版本更新,它在 Redis 社区中被广泛采用,因为它引入了许多增强功能和改进。Redis 是一个高性能的键值存储系统,常用于数据库、缓存和消息代理服务。让我们深入探讨 Redis 3.2 版本中的关键...
Redis 是一个高性能的键值对存储系统,常用于数据缓存、消息队列以及数据库功能。...不过,由于提供的信息中未提及具体2.42版本的变更,以上分析基于一般性的Redis特性,实际更新内容需参考官方文档或变更日志。