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事务功能的实现原理,本来是想用一篇文章进行总结的,写完以后发现这块内容比较多,而且多个命令之间又互相依赖,放在一篇文章里一方面篇幅会比较大,另一方面文章组织结构会比较乱,不容易 ...
随机推荐
- iframe 父子页面方法调用
在写代码的时候经常会用到将一个网页嵌入到另一个网页中,w3c也规定了一个标签<iframe>,这个标签本身就支持跨域,而且所有的浏览器都支持 iframe具有以下属性: 1.framebo ...
- 接口测试-jmeter
一.jmeter下载安装 1)安装jdk(见博文<windows上安装jdk>) 2)在jmeter官网下载 http://jmeter.apache.org/download_jmet ...
- Java实现的高效计数器
本文转载地址: http://blog.csdn.net/snarlfuture/article/details/17049731 在统计来自数据库或文本中某些内容的频率时,你可 ...
- 开涛spring3(12.3) - 零配置 之 12.3 注解实现Bean定义
12.3 注解实现Bean定义 12.3.1 概述 前边介绍的Bean定义全是基于XML方式定义配置元数据,且在[12.2注解实现Bean依赖注入]一节中介绍了通过注解来减少配置数量,但并没有完全 ...
- hadoop 2.7.3 集群安装
三台虚拟机,centos6.5 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 :: loca ...
- CCNP第一课:默认路由(路由黑洞,路由终结)
一:功能实现 R1的环回口由R3控制下放,下放之后R4才可以ping通 代码: R1: 只需要一条静态路由,能回包就行了 ip route 20.1.1.0 255.255.255.0 10.1.1. ...
- arcgis sde 导出栅格文件失败,提示“Database user name and current user schema do not match ”.
具体错误/警告如下: 翻译一下:数据库用户名和当前用户数据库对象的集合不匹配 没有空间参考存在 数据库表没找到 主要还是第一句的问题. 解决方法:切换当前sde账户为能够写入sde的账户,这块不是很了 ...
- Python3网络爬虫
# 最近在实验楼学习了爬取妹子图,发现在运行的时候不是很流畅,有些图片下 1 # coding: utf-8 # coding: utf-8 import re import threading fr ...
- python 读取Excel(二)之xlwt
今天由于在接口测试报告中感觉自己写的接口测试报告特别low,Excel的连个颜色都不加,就想着怎么去想办法给整整,自己根据API一次次调试,感觉很慢,于是乎,百度,可惜没有找到,去官网,官网给的也特别 ...
- 放大镜原生js
<!DOCTYPE html><html><head> <title></title> <style type="text/ ...