Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 本文全面阐述了Redis事务的特性、原理、具体命令操作,指出Redis事务具有原子性但不保证一致性、持久性和隔离性,并解释了Redis事务的适用场景和WATCH命令的乐观锁机制。

1、复习 MySQl 事务的特性

  • 原子性:事务是原子的,它被视为一个不可分割的工作单元。事务中的所有操作要么全部执行成功,要么全部失败回滚,不存在中途状态。原子性确保了数据库的一致性。
  • 一致性:事务执行之前,和之后,数据都不能离谱,维护数据库的一致性,和原子性密切相关
  • 持久性:一旦事务提交,其结果应该是永久性的(存硬盘),即使在系统发生故障的情况下也不会丢失。数据库的持久性保证了数据的长期存储。
  • 隔离性:多个事务可以并发执行,但其结果必须与按某种顺序串行执行的结果一致。隔离性确保一个事务的执行不会被其他事务干扰,通过隔离性可以避免一些并发引起的问题,如脏读(dirty read)、不可重复读(non-repeatable read)和幻读(phantom read)

一致性举例:在一个mysql的事务操作中,事务要么全部执行成功,要么全部失败回滚,不可以有的成功,有的失败,以维护数据库的一致性

2、Redis 事务特性

2.1、原子性(有没有存在争议)

  • 最原本的含义,是把多个操作打包到一起,要么全部执行,要么全部不执行
  • Redis 确实做到了上述的含义,但如果事务中若干个操作,存在有失败的,那就失败吧,不会有回滚操作
  • 相比来说MySQL这里的原子性,走得更远,也是把多个操作打包到一起,要么全都执行成功,要么全都不执行
  • 如果mysql的事务中有操作执行失败,则进行回滚!把中间已经执行的操作,全都回退了
  • 不得不说,MySQL在这方面成为了“标兵”,提高了“原子性”的门槛
  • 这就使人们谈到原子性的时候,更多的是想到的MySQL这种带有回滚的原子性

网上看到,有的人说,redis事务有原子性,有的说没有原子性

  • 说有原子性的原因是因为:它确实满足了原子性最基本的含义,将任务打包执行(也只是打包一起执行了)
  • 说没有原子性的原因是因为:它没有满足mysql那种事务原子性的操作,他们认为原子性应该是打包一起执行+带有回滚,而明显,redis只是打包一起执行,失败不回滚,这种操作不被他们认为是原子性

2.2、一致性、持久性、隔离性(没有)

不具备一致性:redis没有约束,也没有回滚机制,事务执行过程中如果某个修改操作出现失败,就可能引起不一致的情况

不具备一致性:redis本身就是内存数据库,数据是存储在内存中的。虽然redis也有持久化机制,但是这里的持久化机制,和事务没有什么直接关系

不具备隔离性:redis是一个单线程模型的服务器程序,所有的请求/事务,都是“串行”执行的(多线程涉及隔离性,redis单线程,和隔离性扯不到一起)

Redis 的事务,主要的意义,就是为了“打包”,避免其他客户端的命令,插队插到中间

3、redis事务举生活例子

  • 我生日这一天,我和媳妇约好了,晚上出去吃烧烤
  • 但是呢,女人嘛,出门是一件麻烦的事情 (化妆...)
  • 我就先到了烧烤店,点了牛肉串若干,羊肉串若干,五花肉若干,点完之后,我告诉服务员,“我这人还没齐,你先把单下着,但是先不着急烤”
  • 过了一会,我媳妇到了,她又加了一盘烤韭菜,又加了两个烤腰子
  • 随后,我告诉服务员:开始考吧!
  • 此时,先点的这些肉 和 后点的韭菜、腰子 是一起烤的
  • 这两组中间,是没有被插队的
  • 这个不插队,不是先抢占位置,而是先让出位置

其实,这就是redis事务一种典型体现,将若干命令打包到一起执行,而且redis事务的执行逻辑也是不立即执行(不抢占位置),下发执行该事务命令后,redis会把当前正在做的事情(比如已经在执行一个事务,会把这个事务做完)做完后,再执行这个事务

4、redis事务的实现方式

  • redis中实现事务,是引入了队列(每个客户端都有一个)
  • 开启事务的时候,此时客户端输入的命令,就会发给服务器并且进入这个队列中(而不是立即执行)
  • 当遇到了“执行事务”命令的时候,此时就会把队列中的这些任务都按照顺序依次执行
  • 这些任务都是在redis主线程中完成的,主线程会把事务中的操作都执行完,再处理别的客户端

5、redis的事务为什么搞得这么简单? 为什么不涉及成和MySQL一样强大呢

  • MySQL的事务,在背后付出了很大的代价
  • 空间上,要花费更多的时间来存储更多的数据
  • 时间上,也要有更大的执行开销
  • 正是因为MySQL上述的问题,才有了redis上场的机会
  • redis想要效率高,必须舍弃掉一些功能

总结: 鱼和熊掌不可兼得!

6、什么时候需要使用到redis的事务呢?以及redis事务的相关逻辑

如果我们把多个操作打包进行,使用事务是比较合适的

比如当我们秒杀商品时,商家放货了5000台,实际如果让5001个人下单成功,就是超卖了

在秒杀商品等情况下就需要redis、的事务了

把每个用户点击购买直到完全下单成功并且商家货物减少这一整个操作合成一个事务进行执行

以前在多线程中,是通过加锁的方式,来避免“插队”的,在redis中就直接使用事务,即可!

逻辑如下:

7、redis事务的具体命令操作

事务三大基本命令 —— 开启、执行、放弃

  • 开启事务 —— MULTI
  • 执行事务 —— EXEC
  • 放弃当前事务 —— DISCARD
  • 开启事务(multi)后,可以编写事务中的具体操作,这些操作不会被执行,但会加入到这个事务中,待执行命令EXEC后 ,redis会着手执行该事务,即依次执行该事务中的所有命令语句
  • discard表示放弃当前事务,相当于刚才没有进行对事务的操作

redis中的 lua 脚本,也能起到类似于事务的效果

官方网站上说,事务这里的任何能实现的效果,都可以使用 lua 脚本代替

代码举例:

  • 当开启事务,并且给服务器发送若干个命令之后,此时服务器重启,此时的这个事务咋办?
  • 此时的效果就等同于discard

8、WATCH —— 监控key

watch 监控某个key是否在事务执行之前,发生了改变

刚才的场景中,就可以使用watch命令来监控这个key

看看这个key在事务的 multi 和 exec 之间,set key 之后,是否在外部被其他客户端修改了

watch开启后,在 NULTI 和 exec间另一个 redis客户端对 key进行了修改,此时提交事务,事务中对 key的操作就不会真正被执行!

watch 的实现原理,类似 “乐观锁”

watch 可以监测一个 key,也可以监测多个 key

乐观锁、悲观锁不是指某个具体的锁,而是指的是某一类锁的特性

  • 乐观锁:加锁之前,就有一个心理预期,预期接下来锁冲突的概率比较低
  • 悲观锁:加锁之前,也有一个心理预期,接下来锁冲突的概率比较高

锁冲突指的是两个线程针对同一个锁加锁,一个能加锁成功,另一个就得阻塞等待

watch的原理:

  • 当执行 watch key 的时候
  • redis就会给这个key安排一个版本号
  • 版本号可以理解成一个“整数”
  • 每次在修改的时候,版本号就会“变大”
  • 然后在执行 事务 中命令的时候
  • 就会做出判定
  • 判定这个key的版本号,和最初 watch 的时候
  • 记录的版本号是否一致!!!
  • 如果一致,说明当前key在事务开启到最终执行这个过程中,没有别的客户端修改,于是才能真正执行这个事务
  • 如果不一致,说明key在其他客户端中改过了,因此此处就直接丢弃事务中的操作,exec返回nil(空)

逻辑图及相关解释如下:

简单解释CAS和ABA,若不理解可以私信博主或者自行查询:

  • Redis Watch 命令给事务提供check-and-set (CAS) 机制。被Watch的Key被持续监控,如果key在Exec命令执行前有改变,那么整个事务被取消。
  • ABA问题是CAS机制的缺陷,大概意思是 A(旧值)-->B(新值)-->A(新值) cas乐观锁会认为A没被修改。 但是redis的watch在这种情况下,依然会提示watch key被修改,事务失败。

    🧸欢迎您于百忙之中阅读这篇博客,📜希望这篇博客给您带来了一些帮助,祝您生活愉快!

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
5月前
|
NoSQL Redis 数据库
Redis的全局命令及相关误区
Redis的全局命令及相关误区
44 0
|
5月前
|
NoSQL 数据处理 调度
【Redis深度专题】「踩坑技术提升」探索Redis 6.0为何必须启用多线程以提升性能与效率
【Redis深度专题】「踩坑技术提升」探索Redis 6.0为何必须启用多线程以提升性能与效率
362 0
|
5月前
|
缓存 NoSQL Shell
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(持久化功能分析)
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(持久化功能分析)
187 0
|
5月前
|
存储 NoSQL 前端开发
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群指令分析—实战篇)
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群指令分析—实战篇)
42 0
|
5月前
|
NoSQL Shell 网络安全
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群功能分析)(二)
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群功能分析)
51 0
|
缓存 NoSQL Redis
Redis从入门到精通之Redis的内部运作机制
Redis采用基于Reactor模式的事件处理模型,这套模型对应于Redis的文件事件处理器(file event handler),并且是Redis高效的事件处理模型的基础。与Netty的线程模型类似,Redis的事件处理模型也是基于Reactor模式设计的,这种模式被广泛应用于高性能IO的开发中。Redis采用单线程模型是Redis高性能的关键所在。Redis通过事件驱动机制和I/O多路复用技术来处理并发请求,避免了多线程间的锁竞争和上下文切换,提高了系统的性能。同时,Redis采用单线程模型还可以更好地利用CPU缓存和内存,简化了系统的设计和实现,更容易实现复制和持久化功能。
134 3
Redis从入门到精通之Redis的内部运作机制
|
存储 缓存 NoSQL
一文讲透 Redis 事务 (事务模式 VS Lua 脚本)
先说结论: Redis 的事务模式具备如下特点: - 保证隔离性; - 无法保证持久性; - 具备了一定的原子性,但不支持回滚; - 一致性的概念有分歧,假设在一致性的核心是约束的语意下,Redis 的事务可以保证一致性。 但 Lua 脚本更具备实用场景,它是另一种形式的事务,他具备一定的原子性,但脚本报错的情况下,事务并不会回滚。Lua 脚本可以保证隔离性,而且可以完美的支持**后面的步骤依赖前面步骤的结果**。
24710 2
一文讲透 Redis 事务 (事务模式 VS Lua 脚本)
|
缓存 运维 NoSQL
redis 持久化 (真实工作中应用方案)
为了防止数据丢失以及服务重启时能够恢复数据,Redis 支持数据的持久化,主要分为两种方式,分别是 RDB 和 AOF;那么实际场景该如何实现呢?以上就是对这次redis持久化机制再次学习的总结与分享,希望能够帮助大家解决一些实际开发中的问题,如果各位大佬有其他更好的看法与观点,欢迎评论区留言和私信。
180 0
|
缓存 监控 NoSQL
【Redis基础指南】推荐给大家的「主从模式」+「缓存穿透」的学习小贴士(提炼优化)
【Redis基础指南】推荐给大家的「主从模式」+「缓存穿透」的学习小贴士(提炼优化)
191 0
【Redis基础指南】推荐给大家的「主从模式」+「缓存穿透」的学习小贴士(提炼优化)
|
监控 NoSQL 关系型数据库
【Redis技术干货】带你彻底认识「事务运行」功能和原理
【Redis技术干货】带你彻底认识「事务运行」功能和原理
117 0