Redis事务原理分析

时间:2022-11-12 20:16:54

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性质里面提到了一些观点,个人不太认同,所以进行了一些对比。

  1. Atomicity

    指的是要么不执行,要么全部执行。当其中一部分执行了,但是另外一部分没有执行,那么作为整个事务,是全部要回滚,都不执行的,而Redis在执行过程中,如果出现操作和类型不一致,则会导致一部分执行,而一部分错误的情况,即不满足原子性。当然,除去部分失误外,还是能够保证原子性的,但是这并不是严格的原子性要求。
  2. Durability

    持久性,事务提交后,无论出现任何情况,包括系统断电之类的,重启后都是可以恢复的。对于Redis来说,即使开启了AOF以及设置为always,也存在命令执行一部分后,系统宕机而导致数据不一致的情况,不能恢复。一般都是通过write-ahead-logging来实现的,即事先写日志,而Redis是边执行边写日志。
  3. Consistency

    一致性,指从一个有效的状态转到另一个有效的状态,不满足上述的两个条件,也无法保存一致性,即会出现中间状态。比如从一个人的账户转到另外一个人上面,执行了转出,但是没有执行转入的时候宕机了,就会导致数据的不一致。
  4. Isolation

    隔离性,在多个事务并发的情况下,事务之间不会被影响。对于Redis来说,事务的执行是串行的,中途不会插入其它命令的执行,所以是满足隔离性的。

WATCH命令实现

WATCH监听Key,首先就要有地方保存监听的Key,Redis针对不同的客户端,会在客户端的结构体里面维护一个WATCH监听Key的列表,以及在Server里面维护一个全局的哈希表,Key为被监听的Key,Value则为一个链表,里面保存了所有监听该Key的客户端。如下图:

Redis事务原理分析

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

Redis事务原理分析

参考资料:

  1. Redis文档:https://redis.io/topics/transactions
  2. 《Redis实战》 ch4.4/ch19
  3. Wiki ACID:https://en.wikipedia.org/wiki/ACID
  4. Wiki write-ahead-logging:https://en.wikipedia.org/wiki/Write-ahead_logging
  5. Wiki shadow paging: https://en.wikipedia.org/wiki/Shadow_paging

Redis事务原理分析的更多相关文章

  1. 一、Redis事务原理分析

    一.Redis事务原理分析 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD.通过 ...

  2. Redis事务的分析及改进

    Redis事务的分析及改进 Redis的事务特性 数据ACID特性满足了几条? 为了保持简单,redis事务保证了其中的一致性和隔离性: 不满足原子性和持久性: 原子性 redis事务在执行的中途遇到 ...

  3. Spring事务原理分析-部分二

    Spring事务原理分析-部分二 说明:这是我在蚂蚁课堂学习了余老师Spring手写框架的课程的一些笔记,部分代码代码会用到余老师的课件代码.这不是广告,是我听了之后觉得很好. 课堂链接:Spring ...

  4. Spring事务原理分析-部分一

    Spring事务原理分析-部分一 什么事务 事务:逻辑上的一组操作,组成这组操作的各个单元,要么全都成功,要么全都失败. 事务基本特性 ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要 ...

  5. redis client原理分析

    代码库地址:https://github.com/garyburd/redigo 1:连接池 2:发送命令 3:解析结果 1:连接池 连接池结构体如下: type Pool struct { // D ...

  6. Redis Pipeline原理分析

    转载请注明出处:http://www.cnblogs.com/jabnih/ 1. 基本原理 1.1 为什么会出现Pipeline Redis本身是基于Request/Response协议的,正常情况 ...

  7. Spring事务原理分析--手写Spring事务

    一.基本概念和原理 1.Spring事务 基于AOP环绕通知和异常通知的 2.Spring事务分为编程式事务.声明事务.编程事务包括注解方式和扫包方式(xml) Spring事务底层使用编程事务(自己 ...

  8. Redis核心原理与实践--事务实践与源码分析

    Redis支持事务机制,但Redis的事务机制与传统关系型数据库的事务机制并不相同. Redis事务的本质是一组命令的集合(命令队列).事务可以一次执行多个命令,并提供以下保证: (1)事务中的所有命 ...

  9. redis源码分析之事务Transaction(上)

    这周学习了一下redis事务功能的实现原理,本来是想用一篇文章进行总结的,写完以后发现这块内容比较多,而且多个命令之间又互相依赖,放在一篇文章里一方面篇幅会比较大,另一方面文章组织结构会比较乱,不容易 ...

随机推荐

  1. mysql集群(双主)

    0.安装 所谓双主基本可以理解为两台服务器互为主备,其核心思路与主备配置相同. 服务器A: 内网IP: 10.44.94.219 服务器B: 内网IP: 10.44.94.97 1.配置服务器A lo ...

  2. sdutoj 2624 Contest Print Server

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2624 Contest Print Server ...

  3. always pick the choice that scares you a little

    “One of my philosophies is to always pick the choice that scares you a little. The status quo, the p ...

  4. sdut 2831 Euclid (几何)

    题目:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2831 题意:给a, b,  c,  d, ...

  5. bzoj3994

    智商太低了 详细题解在这里http://blog.csdn.net/zmoiynlp/article/details/45176129 ; ..max] of longint; g:..max] of ...

  6. rspec学习02

    元数据 RSpec-core存储元数据哈希每实例和组,其中包含他们的描述,声明的位置等等,这个hash控制很多RSpec核心的功能,包括输出格式化程序(访问描述和位置),和before,after钩子 ...

  7. java学习——网络编程UDP

    UDP 将数据及源和目的封装成数据包中,不需要建立连接 每个数据报的大小限制在64k内 因无连接,是不可靠协议 不需要建立连接,速度快 TCP 建立连接,形成传输数据的通道 在连接中进行大数据量传输 ...

  8. 4. c++ 静态 对象

    参考自文章:http://blog.csdn.net/wpf_ml/article/details/7763534 1. 静态存储 变量定义在函数外或是用static 关键字修饰的变量存放在静态存储区 ...

  9. AndroidStudio文件夹结构视图讲解

    近期,Google已经打算废弃Eclipse.而要大力支持他的亲生儿子AndroidStudio了,已经不在维护Eclipse了,也就是说在Eclipse上面出了什么问题.Google已经不在会管了, ...

  10. mysql最大连接数问题

    进入mysql系统就, 查询最大连接数:show variables like 'max_connections'; 修改最大连接数:set global max_connections=1000;