Redis 事务

原创 2012年10月28日 17:43:32
Redis 提供的事务机制与传统的数据库事务有些不同,传统数据库事务必须维护以下特性:原子性(Atomicity),  一致性(Consistency),  隔离性(Isolation),  持久性(Durability),简称ACID。
我们逐项考察下 Redis 在事务的 ACID 上做出的权衡与取舍:

原子性(Atomicity)
原子意味着操作的不可再分,要么执行要么不执行。Redis 本身提供的所有 API 都是原子操作,那么 Redis 事务其实是要保证批量操作的原子性。Redis 实现批量操作的原理是在一个事务上下文中(通过 MULTI命令开启),所有提交的操作请求都先被放入队列中缓存,在 EXEC 命令提交时一次性批量执行。这样保证了批量操作的一次性执行过程,但 Redis 在事务执行过程的错误情况做出了权衡取舍,那就是放弃了回滚。
Redis 官方文档对此给出的解释是:
  1. Redis 操作失败的原因只可能是语法错误或者错误的数据库类型操作,这些都是在开发层面能发现的问题不会进入到生产环境,因此不需要回滚。
  2. Redis 内部设计推崇简单和高性能,因此不需要回滚能力。
据实而说第一条说法感觉有点站不住脚,可以想象得到 Redis 操作失败的原因绝对不止语法层面的错误,特别是一些像依赖操作系统、文件系统的操作。第二条说法更实在,Redis 的应用场景明显不是为了数据存储的高可靠而设计的,而是为了数据访问的高性能而设计,设计者为了简单性和高性能而部分放弃了原子性。
出于以上考虑 Redis 的事务执行有以下特点:
  1. 批量操作在发送 EXEC 命令前被放入队列缓存
  2. 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行
  3. 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中
一致性(Consistency)
一致性意味着事务结束后系统的数据依然保证一致。在事务开始之前,数据保持有效的状态,事务结束后也如此。显然在前面讨论原子性时,Redis 舍弃了回滚的设计,基本上也就舍弃对数据一致性的有效保证。不过对于一个高效的 key-value store 或 data structure server,数据操作一致性很多时候更多应该依赖应用层面,事实也是我们使用 Redis 时很多时候都是分片和集群的,数据一致性无法依靠任何事务机制。

隔离性(Isolation)
隔离性保证了在事务完成之前,该事务外部不能看到事务里的数据改变。也不能访问一些中间状态,因为假如事务终止的话,这些状态将永远不会发生。Redis 采用单线程设计,在一个事务完成之前,其他客户端提交的各种操作都无法执行因此自然没法看见事务执行的中间状态,隔离性得到保证。

持久性(Durability)
Redis 一般情况下都只进行内存计算和操作,持久性无法保证。但 Redis 也提供了2种数据持久化模式,SNAPSHOT 和 AOF,SNAPSHOT的持久化操作与命令操作是不同步的,无法保证事务的持久性。而AOF模式意味着每条命令的执行都需要进行系统调用操作磁盘写入文件,可以保证持久性,但会大大降低 Redis 的访问性能。

Redis 在2.6版本开始提供脚本(Lua scripting)能力,一种更灵活的批量命令组织方式用于取代目前的事务机制。脚本提供了更强大和灵活的编程能力,但也是一把双刃剑,由于 Redis 需要保证脚本执行的原子性和隔离性,脚本执行期间会阻塞其他命令的执行,因此建议写一些高效的脚本。不过从开发者的角度来说使用Lua脚本的成本(学习成本、开发成本、维护成本)都要更大,特别是一些开发者如果将应用的业务逻辑放入脚本中来执行,是不是让人想起了数据库的存储过程。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Redis研究(七)—如何判断set/get是否为原子操作

在做项目过程中,多个客户端可能同时读写Redis数据库,set和get命令是否为原子操作,关系到命令是否需要加锁机制的必要性。网上资料或者看书都说set和get等Redis命令为原子操作,但是程序里怎...

分布式缓存--序列3--原子操作与CAS乐观锁

问题的提出我们知道,在单机的“线程模型“中,2个线程并发修改一个变量,是需要加锁的。这个在Java并发编程–序列1已经讲过,要么是悲观锁,要么是乐观锁。 如果把单机的线程模型,改成有客户端/服务器的...

使用Redis SETNX 命令实现分布式锁

使用Redis的 SETNX 命令可以实现分布式锁,下文介绍其实现方法。SETNX命令命令格式 SETNX key value 将 key 的值设为 value,当且仅当 key 不存在 若给定...
  • lihao21
  • lihao21
  • 2015年10月13日 21:31
  • 41906

Redis基本操作

From : http://www.cnblogs.com/stephen-liu74/archive/2012/02/13/2349815.html 一、概述:       ...
  • mniwc
  • mniwc
  • 2014年01月22日 20:31
  • 4215

Redis 事务是原子性的吗

Redis 事务是原子性的吗 转自:http://blog.csdn.net/mindfloating/article/details/8121479/ Redis 提供的事务机制与传统的数据库事...

基于Redis实现分布式锁

在很多互联网产品应用中,有些场景需要加锁处理,比如:秒杀,全局递增ID,楼层生成等等。大部分的解决方案是基于DB实现的,Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对R...
  • ugg
  • ugg
  • 2014年12月12日 16:33
  • 144411

redis 事务实现原理

一:简介Redis事务通常会使用MULTI,EXEC,WATCH等命令来完成,redis实现事务实现的机制与常见的关系型数据库有很大的却别,比如redis的事务不支持回滚,事务执行时会阻塞其它客户端的...
  • bugall
  • bugall
  • 2016年08月31日 16:53
  • 3555

redis的类型、原理及使用场景

转自:http://blog.csdn.net/hguisu/article/details/8836819 1.  MySQL+Memcached架构的问题 Me...

redis事务

1.原子性: redis执行批量操作前,先开启mutil命令,然后将操作请求加入队列缓存(list lpush 操作) ,收到exec命令后,进入事务执行,队列中操作失败不影响其他操作 事务执行过...

Redis集群方案及实现

之前做了一个Redis的集群方案,跑了小半年,线上运行的很稳定,还没出过大的状况差不多可以跟大家分享下经验,之前写了一篇文章 数据在线服务的一些探索经验,简单介绍了Reids在我们这边的应用应用我们的...
  • yfkiss
  • yfkiss
  • 2014年08月30日 17:20
  • 79518
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Redis 事务
举报原因:
原因补充:

(最多只允许输入30个字)