`
m635674608
  • 浏览: 5055150 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Redis事务的分析及改进

 
阅读更多

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事务(单库),无法满足这个要求;

可能的解决方案:

  1. 可以考虑使用多个库,读写分离,查询库只用来查询,更新库用来开事务做写操作;

  2. 不再使用redis的事务指令,自己在客户端将待执行的命令批量打包,决定是否回滚还是全部执行;这样可以在更新的间隙执行查询逻辑;而不需要将查询逻辑提前到事务指令multi之前;

  3. 将查询业务逻辑提前;严格规范代码编写要求,所有的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服务器执行,减少网络交互,优化性能,可能的解决方案:

  1. 对于所有的get/set操作,可使用现有的mget/mset指令;
  2. 对于各种不同类型的更新操作,可使用lua脚本将命令打包后,发送到服务器端一次执行;

参考

http://redisbook.readthedocs.org/en/latest/feature/transaction.html

http://www.cnblogs.com/me115/p/4326375.html

 

 

分享到:
评论

相关推荐

    【redis-7.0.15】

    Redis是一款高性能的键值对数据库,它以C语言编写,支持网络,是完全开源的,拥有丰富的数据结构,如字符串、哈希、列表、集合、有序集合等,同时还提供了发布/订阅、事务、持久化、主从复制等功能,广泛应用于缓存...

    redis视图化工具

    6. 事务管理:支持Redis事务的执行和查看,确保操作的原子性。 7. 备份与恢复:方便地备份Redis数据,并在需要时进行恢复。 8. 配置管理:查看和修改Redis服务器的配置参数,优化性能。 总的来说,这款Redis视图化...

    Redis安装包 Redis-x64-3.2.100.zip

    在3.2版本中,Redis引入了一些关键特性,同时也进行了一系列的优化和改进,使得其在Windows平台上的性能更加稳定和高效。 1. 安装过程:Redis-x64-3.2.100.msi是Windows Installer包,通过双击运行可以引导用户进行...

    Redis数据库 v6.2.14.zip

    对于学习和研究Redis,特别是进行毕业设计或计算机案例分析的人员,了解和分析Redis源码可以帮助深入理解数据库的内部工作原理,提升系统设计和优化的能力。同时,通过源码学习,也可以为自定义Redis插件或扩展提供...

    win-redis6压缩包 解压即用

    Redis 6.0.16 版本带来了许多改进和新特性: 1. **多线程支持**:Redis 6 引入了多线程模式,通过后台线程处理网络 I/O,提高了处理大量并发连接的能力,从而提升了性能。这使得 Redis 在高并发场景下表现更优。 2...

    redis-5.0.5.zip windows版本

    Redis 5.0.5是Redis的一个稳定版本,带来了多项改进和优化。以下将详细介绍Redis及其5.0.5版本在Windows下的安装与使用、主要特性以及相关配置知识。 1. **安装与运行** - 解压"redis-5.0.5.zip"至任意目录,如"C:...

    redis-3.0.7-免编译

    此外,Redis还支持事务(Transactions)、发布/订阅(Publish/Subscribe)模式以及 Lua 脚本执行,进一步增强了其功能。 免编译版本意味着用户可以直接在操作系统上运行,无需关心编译环境和依赖项。这通常包括所有...

    spring-data-redis 1.7.6

    4. **事务支持**:Spring Data Redis允许开发者使用`RedisTransactionManager`来管理Redis的事务,提供了与传统关系型数据库相似的事务操作能力,如BEGIN、COMMIT、ROLLBACK等。 5. **持久化策略**:Spring Data ...

    redis.googlecode.com.zip

    例如,最初的版本可能仅支持基本的数据操作,而随着版本的迭代,Redis添加了事务(Transactions)、发布/订阅(Publish/Subscribe)功能,以及主从复制(Replication)。在性能方面,Redis不断优化其命令处理速度和...

    Redis 4.x Cookbook中文版

    3. **事务**: Redis支持事务,允许一次性执行多个操作,保证了操作的原子性。 4. **发布/订阅**: Redis提供消息发布与订阅功能,用于实现简单的消息传递和实时通信。 5. **主从复制**: Redis支持主从复制,可以创建...

    最新版linux redis-6.2.4.tar.gz

    1. AOF持久化改进:Redis 6.2.4增强了Append Only File (AOF) 持久化策略,提供了更高效的重写机制,减少了磁盘占用。 2. Lua脚本增强:支持更多内建函数,如`random`和`sha1hex`,使得Lua脚本功能更加强大。 3. ...

    redis linux

    4. **事务**: Redis支持简单事务,允许用户一次性执行多个操作,确保原子性。 5. **Lua脚本**: Redis 2.4引入了Lua脚本功能,允许用户编写简单的脚本并在服务器端执行,提高处理复杂操作的效率。 **Redis 2.6.8** ...

    redis-6.0.9.tar.gz redis-6.0.6.tar.gz,redis-4.0.11.tar.gz

    5. **事务**:Redis支持简单的事务机制,允许一次执行多个操作,确保原子性。 6. **发布/订阅**:Redis的发布订阅(Pub/Sub)模式使得可以构建实时的消息系统,让多个客户端可以订阅同一主题并接收消息。 7. **Lua...

    最新版redis redis-6.0.7.tar.gz

    3. **事务改进**:尽管Redis不支持ACID事务,但6.0.7对事务执行效率进行了优化,提升了并发性能。 4. **多线程**:Redis 6 引入了IO多线程,提高了网络I/O性能,但命令执行仍保持单线程,以维护简单性和一致性。 5. ...

    linux redis5 .zip

    Redis支持事务,可以批量执行命令,保证命令的原子性。使用`MULTI`、`EXEC`命令来开启和结束一个事务。 4. **发布/订阅(Publish/Subscribe)**: Redis允许通过频道进行消息的发布与订阅,实现简单的消息传递。 5...

    Redis-x64-5.0.14 无需安装版

    4. **事务支持**:Redis 支持原子的多操作事务,确保一系列操作要么全部成功,要么全部失败。 5. **主从复制**:Redis 可以设置为主从模式,实现数据备份和负载均衡。主节点负责写操作,从节点负责读操作,提高了...

    Redis-x86-6.0.8.zip

    Redis 6.0.8是Redis的一个稳定版本,它包含了自Redis 6.0.0发布以来的一系列更新和改进,旨在增强性能、安全性和功能。对于32位Windows用户来说,这是一个重要的发布,因为通常Redis主要针对64位系统优化,而此版本...

    redis3.2 版本

    Redis 3.2 是一个重要的版本更新,它在 Redis 社区中被广泛采用,因为它引入了许多增强功能和改进。Redis 是一个高性能的键值存储系统,常用于数据库、缓存和消息代理服务。让我们深入探讨 Redis 3.2 版本中的关键...

    redis 数据库

    Redis 是一个高性能的键值对存储系统,常用于数据缓存、消息队列以及数据库功能。...不过,由于提供的信息中未提及具体2.42版本的变更,以上分析基于一般性的Redis特性,实际更新内容需参考官方文档或变更日志。

Global site tag (gtag.js) - Google Analytics