2022年Redis最新面试题第3篇 - Redis事务
事务
- 怎么理解 Redis 事务?
- Redis事务执行过程
- Redis事务的一些使用场景
- Redis事务与Redis pipeline的区别
- 集群模式下Redis事务如何保证原子性
怎么理解 Redis 事务?
出现概率: ★★★★
Redis事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行的执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
总结说:Redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。
1)、Redis事务相关命令和使用
MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务相关的命令。
- MULTI: 开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来原子化执行这个命令系列。
- EXEC: 执行事务中的所有操作命令。
- DISCARD: 取消事务,放弃执行事务块中的所有命令。
- WATCH: 监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。
- UNWATCH: 取消WATCH对所有key的监视。
example:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET name '漫步coding'
QUEUED
127.0.0.1:6379> SET brief '一个专注于算法、数据库、职场的公众号'
QUEUED
127.0.0.1:6379> GET name
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
3) "漫步coding"
画重点, Redis事务不支持Rollback
事实上Redis命令在事务执行时可能会失败,但仍会继续执行剩余命令而不是Rollback(事务回滚)。如果你使用过关系数据库,这种情况可能会让你感到很奇怪。然而针对这种情况Redis官方也给出了解释:
Redis命令可能会执行失败,仅仅是由于错误的语法被调用(命令排队时检测不出来的错误),或者使用错误的数据类型操作某个Key: 这意味着,实际上失败的命令都是编程错误造成的,都是开发中能够被检测出来的,生产环境中不应该存在。(这番话,彻底甩锅,“都是你们自己编程错误,与我们无关”。)
由于不必支持Rollback,Redis内部简洁并且更加高效。
Redis事务执行过程
出现概率: ★★★
一个Redis事务从开始到执行会经历以下三个阶段:
- 1)开始事务。
- 2)命令放入Queue。
- 3)执行事务。
1)开始事务
MULTI命令的执行标记着事务的开始:
127.0.0.1:6379> MULTI
OK
这个命令唯一做的就是, 将客户端的 REDIS_MULTI 选项打开, 让客户端从非事务状态切换到事务状态。
2)命令放入Queue
当客户端处于非事务状态下时, 所有发送给服务器端的命令都会立即被服务器执行:
127.0.0.1:6379> SET name '漫步coding'
OK127.0.0.1:6379> GET name
"漫步coding"
但是, 当客户端进入事务状态之后, 服务器在收到来自客户端的命令时, 不会立即执行命令, 而是将这些命令全部放进一个事务队列里, 然后返回QUEUED, 表示命令已入队:
127.0.0.1:6379> MULTI
OK127.0.0.1:6379> SET name "漫步coding"
QUEUED127.0.0.1:6379> GET name
QUEUED
3)执行事务
当客户端进入事务状态之后, 客户端发送的命令就会被放进事务队列里。
EXEC 、 DISCARD 、 MULTI 和 WATCH 这四个命令 —— 当这四个命令从客户端发送到服务器时, 它们会像客户端处于非事务状态一样, 会被服务器立即执行。
127.0.0.1:6379> EXEC
1) OK
2) OK
3) "漫步coding"
4)、关于WATCH命令
WATCH指令,有点类似乐观锁,事务提交时,如果 key 的值已被别的客户端改变,比如某个 list 已被别的客户端push/pop 过了,整个事务队列都不会被执行。(当然也可以用 Redis 实现分布式锁来保证安全性,属于悲观锁)
WATCH机制的作用是,在事务执行前,监控一个或多个键的值变化情况,当事务调用EXEC命令执行时,WATCH机制会先检查监控的键是否被其它客户端修改了。如果修改了,就放弃事务执行,避免事务的隔离性被破坏。然后,客户端可以再次执行事务,此时,如果没有并发修改事务数据的操作了,事务就能正常执行,隔离性也得到了保证。
WATCH机制的具体实现是由WATCH命令实现的,我给你举个例子,你可以看下面的图,进一步理解下WATCH命令的使用。
example:
127.0.0.1:6379>set k 1
OK
127.0.0.1:6379>WATCH k
OK
127.0.0.1:6379>set k 2
OK
127.0.0.1:6379>MULTI
OK
127.0.0.1:6379>set k 3
QUEUED
127.0.0.1:6379>EXEC
(nil)
127.0.0.1:6379>get k
"2"
提交事务,但k值不会被修改为3,因为在事务开启之前k的值被修改了。
Redis事务的一些使用场景
出现概率: ★★★
可利用watch命令监听key,实现乐观锁,来保证不会出现冲突,应用场景比如秒杀来防止超卖。
秒杀场景伪代码如下:
这块代码其实还没有想好, 如果有经验的朋友,欢迎留言, 后续我研究透彻会也专门写一篇秒杀场景的文章。
set total_quantity 100
WATCH goods_quantity
MULTI
if goods_quantity < total_quantity && user_id not in 'user_list'incr goods_quantityset 'user_list' user_id
end
EXEC
Redis事务与Redis pipeline的区别
出现概率: ★★★
Redis Pipeline主要用于批量发送命令,一次性发送多个请求,一次性读取所有返回结果。可以节省连接->发送命令->返回结果这个过程所产生的时间(RTT),减少read()和write()的系统调用(从用户态到内核态之间的切换)次数。
Redis事务、Redis Pipeline表面上它们可以作为批量执行命令的方式,但实际也有许多区别。
1)、命令缓冲队列方式不同
Redis事务包含的命令是缓冲在服务端内存队列,而Redis Pipeline则是缓冲在客户端本地内存中;
2)、请求次数不同
Redis事务中每个命令都需要发送到服务端,而Pipeline只需要发送一次,请求次数更少;
3)、原子性保证
Redis事务可以保证命令原子化执行,而Pipeline不保证原子性。
Redis事务、Pipeline都只能作用于单个节点。集群环境下,执行Redis命令时,会根据key计算出一个槽位(slot),然后根据槽位重定向到特定的节点上执行操作。
4)、在使用事务时,建议配合 Pipeline 使用。
a) 如果不使用 Pipeline,客户端是先发一个 MULTI 命令到服务端,客户端收到 OK,然后客户端再发送一个个操作命令,客户端依次收到 QUEUED,最后客户端发送 EXEC 执行整个事务(文章例子就是这样演示的),这样消息每次都是一来一回,效率比较低,而且在这多次操作之间,别的客户端可能就把原本准备修改的值给修改了,所以无法保证隔离性。
b) 而使用 Pipeline 是一次性把所有命令打包好全部发送到服务端,服务端全部处理完成后返回。这么做好的好处,一是减少了来回网络 IO 次数,提高操作性能。二是一次性发送所有命令到服务端,服务端在处理过程中,是不会被别的请求打断的(Redis单线程特性,此时别的请求进不来),这本身就保证了隔离性。我们平时使用的 Redis SDK 在使用开启事务时,一般都会默认开启 Pipeline 的,可以留意观察一下。
集群模式下Redis事务如何保证原子性
出现概率: ★★★
Redis事务中每个命令都需要发送到服务端, 不过Redis事务可以保证命令原子化执行
Redis事务只能作用于单个节点。集群环境下,执行Redis命令时,会根据key计算出一个槽位(slot),然后根据槽位重定向到特定的节点上执行操作。
更多的java课程学习路线,笔记,面试等架构资料,需要的同学可以私信我(面试)即可免费获取!
2022年Redis最新面试题第3篇 - Redis事务相关推荐
- 2022年Redis最新面试题第8篇 - Redis缓存问题
缓存问题 分布式缓存 Redis缓存雪崩 Redis缓存击穿 Redis缓存穿透 缓存预热 缓存降级 Redis缓存雪崩 出现概率: ★★★★★ 这个在Redis面试的题目中算是出镜率特别高的问题了, ...
- 2022年Redis最新面试题
2022年Redis最新面试题 一.Redis基础知识 1.什么是 Redis, 有哪些优缺点? 2.Redis 最适合的场景, 可以简单的说说吗? 3.Redis 相比 Memcached 有哪些优 ...
- 2022年MySQL最新面试题
2022年MySQL最新面试题目录 前言 一.数据库基础知识 0.概要 1.平时MySQL主要用哪个版本 2.数据库三大范式是什么 3.MySQL有关权限的表都有哪几个 4.MySQL的binlog有 ...
- 2020前端最新面试题(vue篇)
2020前端最新面试题(vue篇) 由于疫情原因,原本每年的"金三银四"仿佛消失,随之而来的是找工作的压力,这里给要面试的小伙伴们总结了到目前为止我遇到的前端面试题,仅供参考哦,第 ...
- 2022年Redis最新面试题- Redis集群
最近整理一份关于Redis常见面试题的,也会根据自己的经验, 标注一些出现的概率,最高5颗★出现的概率最高.比如这样: Redis 最适合的场景, 可以简单的说说吗? 出现概率: ★★★★ 整体目录大 ...
- 2022年Redis最新面试题- Redis分布式锁
最近整理一份关于Redis常见面试题的,也会根据自己的经验, 标注一些出现的概率,最高5颗★出现的概率最高.比如这样: Redis 最适合的场景, 可以简单的说说吗? 出现概率: ★★★★ 整体目录大 ...
- 2022年Redis最新面试题 - Redis缓存问题
缓存问题 分布式缓存 Redis缓存雪崩 Redis缓存击穿 Redis缓存穿透 缓存预热 缓存降级 #Redis缓存雪崩 出现概率: ★★★★★ 这个在Redis面试的题目中算是出镜率特别高的问题了 ...
- 为什么redis取出来是null_[2020] Redis 最新面试题
Redis 的数据类型(数据结构) string (二进制安全,可以存储任意类型的数据) list(链表) 字典(就是hashmap) set(不重复无序的hashmap) zset(按照给定的 sc ...
- java面试题及答案2022,java2022最新面试题及答案
发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一.Java 基础 1. JDK 和 J ...
最新文章
- 译者招募 | 《Java编程思想》作者Bruce Eckel新作On Java 8
- java 并发队列_JAVA并发编程:阻塞队列BlockingQueue之SynchronousQueue
- 矩形变弧度角_在上海做下颌角整形这些医生错过后悔都来不及,案例分享
- 【论文阅读和实现】On Spectral Clustering: Analysis and an algorithm【Python实现】
- linux 优化内存分配,Linux性能优化 第三章 性能工具:系统内存
- HDU 5944 Fxx and string(暴力/枚举)
- 原生JS获取地址了参数
- JAVA中“:”的用法详解
- php语句过滤掉html标签_php过滤HTML标签、属性等正则表达式
- URLEncoder和URLDecoder;cookie中保存特殊字符以及URL中乱码问题解决方案
- ffmpeg编码:xavc 42210bit+mxf
- linux系统live管理界面,live-系统爱好者
- 在线教育发展前景广阔
- YOLO3+GPU(gtx1060)
- qt vs tools
- python CV 趣味项目 答题卡识别
- 在CygWin中设置proxy
- 批量下载文件并重命名
- CodeBlocks+wxWidgets
- GitHub如何配置SSH Key