Redis事务原理分析
Redis事务原理分析
基本应用
在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待。由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD。
通过WATCH,可以实现CAS操作。使用WATCH监听一些键,然后去检查键的值,然后根据键的值来决定是否还需要进行MULTI,如果键的值被改了,则重新。(因为有可能在执行WATCH前,键的值被改了,所以需要先WATCH,然后再作判断)。在执行MULTI命令后,如果中途WATCH的键的值被修改了,后续再执行EXEC时,整个事务都会被终止。
CAS使用示例:
假设存在一个String类型的状态值,state,需要对其进行CAS操作:
WATCH state
value = GET state;
if value == 1
UNWATCH state
Return false;
MULTI
SET state 1
result = EXEC
if result == success
return true;
return false;
原理
Redis事务实现原理
通过上述的基本应用可以知道,Redis是通过WATCH命令,来保证当前事务的数据是否被修改过,如果被修改了,则整个事务会中止,不再执行。那么,Redis在实现的时候,会保存对应的watch key,然后中途如果该Key被修改了,则会将对应的所有客户端的标志位都置为CLIENT_DIRTY_CAS,表示数据被修改,后续执行EXEC的时候则会被中断,从而实现事务。而UNWATCH命令则是从保存的watch_keys里面移除。MULTI命令仅仅将客户端的标志位flags置为CLIENT_MULTI,表示处于MULTI状态,该状态下,后续的命令(除了MULTI/WATCH/DISCARD/EXEC)外,其它命令都会被保存到一个列表里面,直到EXEC或者DISCARD命令执行。如果中途出现了语法错误之类的命令,则会将flags置为CLIENT_DIRTY_EXEC。后续执行EXEC时,如果flags存在CLIENT_DIRTY_CAS或者CLIENT_DIRTY_EXEC,则整个事务会被中止,不执行任何命令。
ACID分析
针对Redis的事务实现,对于ACID,个人认为,对于Atomicity和Durability以及Consistency,Redis是不满足的。为什么会对ACID进行分析呢,一部分原因是为了作对比学习,另一部分是因为《Redis设计与实现》19章事务ACID性质里面提到了一些观点,个人不太认同,所以进行了一些对比。
- Atomicity
指的是要么不执行,要么全部执行。当其中一部分执行了,但是另外一部分没有执行,那么作为整个事务,是全部要回滚,都不执行的,而Redis在执行过程中,如果出现操作和类型不一致,则会导致一部分执行,而一部分错误的情况,即不满足原子性。当然,除去部分失误外,还是能够保证原子性的,但是这并不是严格的原子性要求。 - Durability
持久性,事务提交后,无论出现任何情况,包括系统断电之类的,重启后都是可以恢复的。对于Redis来说,即使开启了AOF以及设置为always,也存在命令执行一部分后,系统宕机而导致数据不一致的情况,不能恢复。一般都是通过write-ahead-logging来实现的,即事先写日志,而Redis是边执行边写日志。 - Consistency
一致性,指从一个有效的状态转到另一个有效的状态,不满足上述的两个条件,也无法保存一致性,即会出现中间状态。比如从一个人的账户转到另外一个人上面,执行了转出,但是没有执行转入的时候宕机了,就会导致数据的不一致。 - Isolation
隔离性,在多个事务并发的情况下,事务之间不会被影响。对于Redis来说,事务的执行是串行的,中途不会插入其它命令的执行,所以是满足隔离性的。
WATCH命令实现
WATCH监听Key,首先就要有地方保存监听的Key,Redis针对不同的客户端,会在客户端的结构体里面维护一个WATCH监听Key的列表,以及在Server里面维护一个全局的哈希表,Key为被监听的Key,Value则为一个链表,里面保存了所有监听该Key的客户端。如下图:

当执行WATCH account时,则首先会判断该Key是否已在客户端里面,如果存在,则直接返回,否则加入到客户端对应的watched_keys列表里面,然后再将其加入到对应DB的watched_keys字典表里面,Key为 account,Value则为该客户端。

参考资料:
- Redis文档:https://redis.io/topics/transactions
- 《Redis实战》 ch4.4/ch19
- Wiki ACID:https://en.wikipedia.org/wiki/ACID
- Wiki write-ahead-logging:https://en.wikipedia.org/wiki/Write-ahead_logging
- Wiki shadow paging: https://en.wikipedia.org/wiki/Shadow_paging
Redis事务原理分析的更多相关文章
- 一、Redis事务原理分析
一.Redis事务原理分析 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD.通过 ...
- Redis事务的分析及改进
Redis事务的分析及改进 Redis的事务特性 数据ACID特性满足了几条? 为了保持简单,redis事务保证了其中的一致性和隔离性: 不满足原子性和持久性: 原子性 redis事务在执行的中途遇到 ...
- Spring事务原理分析-部分二
Spring事务原理分析-部分二 说明:这是我在蚂蚁课堂学习了余老师Spring手写框架的课程的一些笔记,部分代码代码会用到余老师的课件代码.这不是广告,是我听了之后觉得很好. 课堂链接:Spring ...
- Spring事务原理分析-部分一
Spring事务原理分析-部分一 什么事务 事务:逻辑上的一组操作,组成这组操作的各个单元,要么全都成功,要么全都失败. 事务基本特性 ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要 ...
- redis client原理分析
代码库地址:https://github.com/garyburd/redigo 1:连接池 2:发送命令 3:解析结果 1:连接池 连接池结构体如下: type Pool struct { // D ...
- Redis Pipeline原理分析
转载请注明出处:http://www.cnblogs.com/jabnih/ 1. 基本原理 1.1 为什么会出现Pipeline Redis本身是基于Request/Response协议的,正常情况 ...
- Spring事务原理分析--手写Spring事务
一.基本概念和原理 1.Spring事务 基于AOP环绕通知和异常通知的 2.Spring事务分为编程式事务.声明事务.编程事务包括注解方式和扫包方式(xml) Spring事务底层使用编程事务(自己 ...
- Redis核心原理与实践--事务实践与源码分析
Redis支持事务机制,但Redis的事务机制与传统关系型数据库的事务机制并不相同. Redis事务的本质是一组命令的集合(命令队列).事务可以一次执行多个命令,并提供以下保证: (1)事务中的所有命 ...
- redis源码分析之事务Transaction(上)
这周学习了一下redis事务功能的实现原理,本来是想用一篇文章进行总结的,写完以后发现这块内容比较多,而且多个命令之间又互相依赖,放在一篇文章里一方面篇幅会比较大,另一方面文章组织结构会比较乱,不容易 ...
随机推荐
- NioSocket相关知识
一.Nio简介 nio 是non-blocking的简称,在jdk1.4 里提供的新api .Sun 官方标榜的特性如下: 为所有的原始类型提供(Buffer)缓存支持.字符集编码解码解决方案. Ch ...
- 2016 UESTC Training for Dynamic Programming
强行做做试试看吧. http://acm.hust.edu.cn/vjudge/contest/124721#overview 密码:mytrain C - 柱爷与咸鱼神功 一个简单01背包. #in ...
- 使用公共 Registry - 每天5分钟玩转 Docker 容器技术(19)
保存和分发镜像的最直接方法就是使用 Docker Hub. Docker Hub 是 Docker 公司维护的公共 Registry.用户可以将自己的镜像保存到 Docker Hub 免费的 repo ...
- 028hibernate缓存(性能优化策略)
一级缓存 二级缓存 查询缓存 缓存是为了提高性能 变化不是很大,相对静态的对象放入缓存 对象的创建比较耗时
- 移动端页面 iPhone + Safari 页面调试 之 正确查看网络请求的姿势
如题 本文主要将 Safari + iPhone 前端开发调试 之 正确查看网络请求的 姿势 惯例 说下问题场景: 早知道safari(Mac) + iPhone 调试的方便 能解决很多日常调试问题 ...
- 数据库连接之SQL JDBC
数据库连接之SQL JDBC SQlServer的配置: 1).外围配置服务器中将远程连接设置为:同时使用TCP/IP和named pipes 2).点击该连接->属性->安全性-> ...
- 数据库MySQL纯净卸载
有些人在安装MySQL后,卸载后再次安装时,一直安装不上去,到最后不得不重装系统来安装MySQL.这里教大家如何将MySQL卸载干净,不影响下次安装. 卸载过程 1.停止mysql服务 2.进行卸载 ...
- LinkedList集合
LinkedList集合特点: 1,有序,允许重复(有序指与添加顺序一致) 2,有下标,可以通过下标获取元素,以及将元素插入指定位置 3,底层使用的数据结构是链表以及堆栈结构,线程不安全 4,链表内存 ...
- HTML----网页基础和基本标签
网页分类: 1.静态网页:所有内容全写死,都写在源代码中,若修改必须修改源代码,后缀为.html或htm 2.动态网页:内容大部分来自于数据库,可以修改,后缀为.aspx(c#).jsp(java). ...
- 加载jquery插件注意了
1.尽量放在</body>之前,不要放在</head>标签之前,如果执意要放也要放在css之后,例如: <link href="style.css" ...