请选择 进入手机版 | 继续访问电脑版

[Redis] Redis事件 为什么不支持回滚

[复制链接]
查看73 | 回复21 | 2021-9-13 23:37:31 | 显示全部楼层 |阅读模式
目次

前言

变乱 是关系型数据库的特性 之一,那么作为

  1. Nosql
复制代码
的代表
  1. Redis
复制代码
中有变乱 吗?假如 有,那么
  1. Redis
复制代码
当中的变乱 又是否具备关系型数据库的
  1. ACID
复制代码
四大特性呢?

Redis 有变乱 吗

这个答案大概 会令很多人感到不测 ,

  1. Redis
复制代码
当中是存在“变乱 ”的。这里我把
  1. Redis
复制代码
的变乱 带了引号,缘故原由 在后面分析。

  1. Redis
复制代码
当中的单个下令 都是原子操作,但是假如 我们必要 把多个下令 组合操作又必要 保证数据的同等 性时,就可以测验 利用
  1. Redis
复制代码
提供的变乱 (或者利用 前面先容 的
  1. Lua
复制代码
脚本)。

  1. Redis
复制代码
当中,通过下面
  1. 4
复制代码
个下令 来实现变乱 :

    1. multi
    复制代码
    :开启变乱
    1. exec
    复制代码
    :实验 变乱
    1. discard
    复制代码
    :取消变乱
    1. watch
    复制代码
    :监视

  1. Redis
复制代码
的变乱 重要 分为以下
  1. 3
复制代码
步:

  • 实验 下令
    1. multi
    复制代码
    开启一个变乱 。
  • 开启变乱 之后实验 的下令 都会被放入一个队列,假如 成功之后会固定返回
    1. QUEUED
    复制代码
  • 实验 下令
    1. exec
    复制代码
    提交变乱 之后,
    1. Redis
    复制代码
    会依次实验 队列内里 的下令 ,并依次返回全部 下令 效果 (假如 想要放弃变乱 ,可以实验
    1. discard
    复制代码
    下令 )。

接下来让我们依次实验 以下下令 来领会 一下

  1. Redis
复制代码
当中的变乱 :

  1. multi //开启事务
  2. set name lonely_wolf //设置 name,此时 Redis 会将命令放入队列
  3. set age 18 //设值 age,此时 Redis 会将命令放入队列
  4. get name //获取 name,此时 Redis 会将命令放入队列
  5. exec //提交事务,此时会依次执行队列里的命令,并依次返回结果
复制代码

实验 完成之后得到如下效果 :

在这里插入图片形貌

Redis 变乱 实现原理

  1. Redis
复制代码
中每个客户端都有记录当前客户端的变乱 状态
  1. multiState
复制代码
,下面就是一个客户端
  1. client
复制代码
的数据布局 定义:

  1. typedef struct client {
  2. uint64_t id;//客户端唯一 id
  3. multiState mstate; //MULTI 和 EXEC 状态(即事务状态)
  4. //...省略其他属性
  5. } client;
复制代码

  1. multiState
复制代码
数据布局 定义如下:

  1. typedef struct multiState {
  2. multiCmd *commands;//存储命令的 FIFO 队列
  3. int count;//命令总数
  4. //...省略了其他属性
  5. } multiState;
复制代码

  1. multiCmd
复制代码
是一个队列,用来吸取 并存储开启变乱 之后发送的下令 ,其数据布局 定义如下:

  1. typedef struct multiCmd {
  2. robj **argv;//用来存储参数的数组
  3. int argc;//参数的数量
  4. struct redisCommand *cmd;//命令指针
  5. } multiCmd;
复制代码

我们以上面变乱 的示例截图中变乱 为例,可以得到如下所示的一个简图:

在这里插入图片形貌

Redis 变乱 ACID 特性

传统的关系型数据库中,一个变乱 一样寻常 都具有

  1. ACID
复制代码
特性。那么现在 就让我们来分析一下
  1. Redis
复制代码
是否也满意 这
  1. ACID
复制代码
四大特性。

A - 原子性

在讨论变乱 的原子性之前,我们先来看

  1. 2
复制代码
个例子。

模拟 变乱 在实验 下令 前发生非常 。依次实验 以下下令 :

  1. multi //开启事务
  2. set name lonely_wolf //设置 name,此时 Redis 会将命令放入队列
  3. get //执行一个不完成的命令,此时会报错
  4. exec //在发生异常后提交事务
复制代码

终极 得到了如下图所示的效果 ,我们可以看到,当下令 入队的时间 报错时,变乱 已经被取消了:

在这里插入图片形貌

模拟 变乱 在实验 下令 前发生非常 。依次实验 以下下令 :

  1. flushall //为了防止影响,先清空数据库
  2. multi //开启事务
  3. set name lonely_wolf //设置 name,此时 Redis 会将命令放入队列
  4. incr name //这个命令只能用于 value 为整数的字符串对象,此时执行会报错
  5. exec //提交事务,此时在执行第一条命令成功,执行第二条命令失败
  6. get name //获取 name 的值
复制代码

终极 得到了如下图所示的效果 ,我们可以看到,当实验 变乱 报错的时间 ,之前已经成功的下令 并没有被回滚,也就是说在实验 变乱 的时间 某一个下令 失败了,并不会影响其他下令 的实验 ,即

  1. Redis
复制代码
的变乱 并不会回滚

在这里插入图片形貌

Redis 中的变乱 为什么不会滚

这个题目 的答案在

  1. Redis
复制代码
官网中给出了明白 的表明 :

在这里插入图片形貌

总结起来重要 就是

  1. 3
复制代码
个缘故原由 :

    1. Redis
    复制代码
    作者以为 发生变乱 回滚的缘故原由 大部分都是程序错误导致,这种环境 一样寻常 发生在开辟 和测试阶段,而生产环境很少出现。
  • 对于逻辑性错误,比如本来应该把一个数加
    1. 1
    复制代码
    ,但是程序逻辑写成了加
    1. 2
    复制代码
    ,那么这种错误也是无法通过变乱 回滚来举行 办理 的。
    1. Redis
    复制代码
    寻求 的是简单高效,而传统变乱 的实现相对比较复杂,这和
    1. Redis
    复制代码
    的计划 头脑 相违背 。

 C - 同等 性

同等 性指的就是变乱 实验 前后的数据符合数据库的定义和要求。这一点

  1. Redis
复制代码
中的变乱 是符合要求的,上面讲述原子性的时间 已经提到,不论是发生语法错误还是运行时错误,错误的下令 均不会被实验 。

I - 隔离性

变乱 中的全部 下令 都会按次序 实验 ,在实验

  1. Redis
复制代码
变乱 的过程中,另一个客户端发出的哀求 不大概 被服务,这保证了下令 是作为单独的独立操作实验 的。以是
  1. Redis
复制代码
当中的变乱 是符合隔离性要求的。

D - 持久性

假如

  1. Redis
复制代码
当中没有被开启持久化,那么就是纯内存运行的,一旦重启,全部 数据都会丢失,此时可以以为
  1. Redis
复制代码
不具备变乱 的持久性;而假如
  1. Redis
复制代码
开启了持久化,那么可以以为
  1. Redis
复制代码
在特定条件下是具备持久性的。

watch 下令

上面我们讲述

  1. Redis
复制代码
中变乱 时,提到的的常用下令 还有一个
  1. watch
复制代码
下令 ,这个又是做什么用的呢?我们还是先来看一个例子。

起首 打开一个客户端一,依次实验 以下下令 :

  1. flushall //清空数据库
  2. multi //开启事务
  3. get name //获取 name,此时正常返回 nil
  4. set name lonely_wolf //设置 name
  5. get name //获取 name,此时正常应该返回 lonely_wolf
复制代码

得到如下效果 图:

在这里插入图片形貌

这时间 我们先不实验 变乱 ,打开另一个客户端二,来实验 一个下令

  1. set name zhangsan
复制代码

在这里插入图片形貌

客户端二实验 成功了,这时间 再返回到客户端一实验

  1. exec
复制代码
下令 :

在这里插入图片形貌

可以发现,第一句话返回了

  1. zhangsan
复制代码
。也就是说,
  1. name
复制代码
这个
  1. key
复制代码
值在入队之后到
  1. exec
复制代码
之前发生了变化,一旦发生这种环境 ,大概 会引起很严肃 的题目 ,以是 在关系型数据库可以通过锁来办理 这种题目 ,那么
  1. Redis
复制代码
当中试怎样 办理 的呢?

是的,在

  1. Redis
复制代码
当中就是通过
  1. watch
复制代码
下令 来处理这种场景的。

watch 下令 的作用

  1. watch
复制代码
下令 可以为
  1. Redis
复制代码
变乱 提供
  1. CAS
复制代码
乐观锁举动 ,它可以在
  1. exec
复制代码
下令 实验 之前,监视恣意
  1. key
复制代码
值的变化,也就是说当多个线程更新同一个
  1. key
复制代码
值的时间 ,会跟原值做比较,一旦发现它被修改过,则拒绝实验 下令 ,并且会返回
  1. nil
复制代码
给客户端。

下面还是让我们通过一个示例来演示一下。

打开一个客户端一,依次实验 如下下令 :

  1. flushall //清空数据库
  2. watch name //监视 name
  3. multi //开启事务
  4. set name lonely_wolf //设置 name
  5. set age 18 // 设置 age
  6. get name //获取 name
  7. get age //获取 age
复制代码

实验 之后得到如下效果 图:

在这里插入图片形貌

这时间 再打开一个客户端二,实验

  1. set name zhangsan
复制代码
下令 :

在这里插入图片形貌

然后再回到客户端一实验

  1. exec
复制代码
下令 。这时间 会发现直接返回了
  1. nil
复制代码
,也就是变乱 中全部 的下令 都没有被实验 (即:只要检测到一个
  1. key
复制代码
值被修改过,那么整个变乱 都不会被实验 ):

在这里插入图片形貌

watch 原理分析

下面是一个

  1. Redis
复制代码
服务的数据布局 定义:

  1. typedef struct redisDb {
  2. dict *watched_keys; //被 watch 命令监视的 key
  3. int id; //Database ID
  4. //...省略了其他属性
  5. } redisDb;
复制代码

可以看到,

  1. redisDb
复制代码
中的
  1. watched_keys
复制代码
存储了一个字典,这个字典当中的
  1. key
复制代码
存的就是被监视的
  1. key
复制代码
,然后字典的值存的就是客户端
  1. id
复制代码
。然后每个客户端还有一个标记属性
  1. CLIENT_DIRTY_CAS
复制代码
,一旦我们实验 了一些如
  1. set
复制代码
  1. sadd
复制代码
等能修改
  1. key
复制代码
值对应
  1. value
复制代码
的下令 ,那么客户端的
  1. CLIENT_DIRTY_CAS
复制代码
标记属性将会被修改,后面实验 变乱 提交下令
  1. exec
复制代码
时发现客户端的标记属性被修改过(乐观锁的表现 ),则会拒绝实验 变乱 。

总结

本文重要 先容 了

  1. Redis
复制代码
当中的变乱 机制,在先容 变乱 实现原理的同时从传统关系型数据库的
  1. ACID
复制代码
四大特性对比分析了
  1. Redis
复制代码
当中的变乱 ,并终极 相识 到了
  1. Redis
复制代码
的变乱 好像 并不是那么“美满 ”。

到此这篇关于Redis变乱 为什么不支持回滚 的文章就先容 到这了,更多相干 Redis变乱 回滚 内容请搜刮 脚本之家从前 的文章或继续欣赏 下面的相干 文章渴望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

avatar 蜡烛2017 | 2021-9-14 01:31:15 | 显示全部楼层
管它三七二十一!
回复

使用道具 举报

avatar 悲新座客 | 2021-9-26 18:56:10 | 显示全部楼层
学习雷锋,好好回帖!
回复

使用道具 举报

avatar 安夕萌mdj | 2021-9-29 19:15:11 | 显示全部楼层
听admin楼主一席话,省我十本书!
回复

使用道具 举报

avatar 红军利物浦2017 | 2021-10-2 15:43:56 | 显示全部楼层
写得实在太好了,我唯一能做的就是默默顶贴!
回复

使用道具 举报

avatar 扮猪吃老虎2017 | 2021-10-7 14:25:38 | 显示全部楼层
顶一个!
回复

使用道具 举报

avatar 老顽童760 | 2021-10-7 21:23:07 | 显示全部楼层
admin楼主说的我也略懂!
回复

使用道具 举报

avatar 深海渔灯每 | 2021-10-10 04:40:39 | 显示全部楼层
admin楼主该去看心理医生了!
回复

使用道具 举报

avatar 向往草原403 | 2021-10-12 21:07:27 | 显示全部楼层
东方不败外加灭绝师太啊!
回复

使用道具 举报

avatar veronica六 | 2021-10-15 20:06:00 | 显示全部楼层
支持一下!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则