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命令为原子操作,但是程序里怎...

Redis研究(十)—Redis事务和生存时间

一、事务概述 Redis事务是一组命令的集合。事务同命令一样是Redis的最小执行单位,要么执行,要么不执行。 事务的原理是先将属于一个事务的命令发送给Redis,然后在让Redis依次执行这些命令。...

redis 事务实现原理

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

华为机试—九宫格(高级题160分,广度优先遍历)

基本思路: 广度优先遍历,每次找到1的位置,分别向上、向下、向左、向右移动。把移动后的每个状态存储到队列中,弹出队头,判断是否为最终结果状态,如果是,输出遍历的层数(即移动步数),如果不是,把现阶段...

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

使用Redis的 SETNX 命令可以实现分布式锁,下文介绍其实现方法。SETNX命令命令格式 SETNX key value 将 key 的值设为 value,当且仅当 key 不存在 若给定...

iptables高性能前端优化-无压力配置1w+条规则

产生本文的故事这显然是个周末,这是一个下雨的周末,这是一个台风登陆的周末…  上周,有一个很猛的台风“天鸽”,当天红警晚发了两个小时,当发布红警时,几乎所有人都到了公司,当然,除了那些怕西装和皮鞋被雨...
  • dog250
  • dog250
  • 2017-08-27 20:36
  • 5000

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

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

浅谈redis、memcache、mongoDB 的优缺点

欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和...

Redis持久化

概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的。所以,我们需要将内存中的数据持...

Dubbo各种协议

原文地址:http://dubbo.io/User+Guide-zh.htm#UserGuide-zh-协议参考手册 协议参考手册 (+) (#) 推荐使用Dubbo协议 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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