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的客户端。如下图:

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

参考资料:

  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. 运维老鸟教你安装centos6.5如何选择安装包

    标签:老男孩教育 Centos6.5安装选包原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://oldboy.blog.51cto.c ...

  2. Ubuntu设置终端相对短路径

    这个设置相对实际上是比较简单的.在自己的家目录打开.bashrc 找到PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$' 只需要将w修改为大写W保存, ...

  3. struts2.1.6教程十一、注解配置

    在此先略去注解配置的实例,具体可以参看官方提供的文档.其实在熟悉struts及相关的一些内容后,再来看文档是比较容易理解得.只是要注意使用注解Annotition时: (1)要多导入一个jar包:st ...

  4. TP框架 增删查

    TP框架添加数据到数据库1.使用数组方式添加造模型对象 2.使用AR方式 强类型语言存在的方式 3.使用自动收集表单添加 :只能用POST方式,提交数据一个操作方法实现两个逻辑:A显示页面B得到数据 ...

  5. 【Netty】WebSocket

    一.前言 前面学习了codec和ChannelHandler之间的关系,接着学习WebSocket. 二.WebSocket 2.1. WebSocket介绍 WebSocket协议允许客户端和服务器 ...

  6. 教你一步搭建Flume分布式日志系统

    在前篇几十条业务线日志系统如何收集处理?中已经介绍了Flume的众多应用场景,那此篇中先介绍如何搭建单机版日志系统. 环境 CentOS7.0 Java1.8 下载 官网下载 http://flume ...

  7. python 集合相关操作

    集合相关操作 集合是一个无序的,不重复的数据组合,它有着两个主要作用:去重以及关系测试. 去重指的是当把一个列表变成了集合,其中重复的内容就自动的被去掉了 关系测试指的是,测试两组数据之间的交集.差集 ...

  8. Python教程(2.5)——控制台输入

    写Python程序时,你可能希望用户与程序有所交互.例如你可能希望用户输入一些信息,这样就可以让程序的扩展性提高. 这一节我们来谈一谈Python的控制台输入. 输入字符串 Python提供一个叫做i ...

  9. 01--数据库MySQL:【数据库DB】和【数据库管理系统DBMS】 简介

    1.数据库DB 数据库:DB(DataBase) 按照一定规则存储在计算机的内部存储设备上被各种用户或者应用共享的数据集合 2.数据库管理系统DBMS 1)数据库管理系统DBMS:DBMS(DataB ...

  10. ajax 动态添加商品列表

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...