大家好,我是散步 coding, 最近在整顿 2022 年 Redis 最新面试题, 大家也能够通过我上面的博客地址在线浏览, 明天讲讲第 3 篇 – Redis 事务。本文首发于公众号: 散步 coding
2022 年 Redis 最新面试题目录
- Redis 基础知识
- Redis 数据结构
- Redis 事务
- Redis 数据长久化
- Redis 集群
- Redis 淘汰策略
- Redis 分布式锁
- Redis 缓存问题
- 运维和部署
事务
- 怎么了解 Redis 事务?
- Redis 事务执行过程
- Redis 事务的一些应用场景
- Redis 事务与 Redis pipeline 的区别
- 集群模式下 Redis 事务如何保障原子性
怎么了解 Redis 事务?
呈现概率: ★★★★
<font color=#FF000 >Redis 事务的实质是一组命令的汇合 </font>。事务反对一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会依照程序串行的执行队列中的命令,其余客户端提交的命令申请不会插入到事务执行命令序列中。
总结说: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"
画重点, <font color=#FF000 >Redis 事务不反对 Rollback</font>
事实上 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'
OK
127.0.0.1:6379> GET name
"散步 coding"
然而,当客户端进入事务状态之后,服务器在收到来自客户端的命令时,不会立刻执行命令,而是将这些命令全副放进一个事务队列里,而后返回 QUEUED,表示命令已入队:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET name "散步 coding"
QUEUED
127.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 命令
<font color=#FF000 >WATCH 指令,有点相似乐观锁 </font>,事务提交时,如果 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"
提交事务,<font color=#FF000 > 但 k 值不会被批改为 3,因为在事务开启之前 k 的值被批改了 </font>。
Redis 事务的一些应用场景
呈现概率: ★★★
可利用 watch 命令监听 key,实现乐观锁,来保障不会呈现抵触,利用场景比方秒杀来避免超卖。
秒杀场景伪代码如下:
这块代码其实还没有想好, 如果有教训的敌人,欢送留言, 后续我钻研透彻会也专门写一篇秒杀场景的文章。
set total_quantity 100
WATCH goods_quantity
MULTI
if goods_quantity < total_quantity && user_id not in 'user_list'
incr goods_quantity
set 'user_list' user_id
end
EXEC
Redis 事务与 Redis pipeline 的区别
呈现概率: ★★★
<font color=#FF000 >Redis Pipeline 次要用于批量发送命令,一次性发送多个申请,一次性读取所有返回后果 </font>。能够节俭连贯 -> 发送命令 -> 返回后果这个过程所产生的工夫(RTT),缩小 read() 和 write() 的零碎调用(从用户态到内核态之间的切换)次数。
Redis 事务、Redis Pipeline 外表上它们能够作为批量执行命令的形式,但理论也有许多区别。
1)、命令缓冲队列形式不同
Redis 事务蕴含的命令是缓冲在服务端内存队列,而 Redis Pipeline 则是缓冲在客户端本地内存中;
2)、申请次数不同
Redis 事务中每个命令都须要发送到服务端,而 <font color=#FF000 >Pipeline 只须要发送一次,申请次数更少 </font>;
3)、原子性保障
Redis 事务能够保障命令原子化执行,而 Pipeline 不保障原子性。
Redis 事务、Pipeline 都只能作用于单个节点。集群环境下,执行 Redis 命令时,会依据 key 计算出一个槽位(slot), 而后依据槽位重定向到特定的节点上执行操作。
4)、<font color=#FF000 > 在应用事务时,倡议配合 Pipeline 应用 </font>。
a) 如果不应用 Pipeline,客户端是先发一个 MULTI 命令到服务端,客户端收到 OK,而后客户端再发送一个个操作命令,客户端顺次收到 QUEUED,最初客户端发送 EXEC 执行整个事务(文章例子就是这样演示的),这样音讯每次都是一来一回,效率比拟低,而且在这屡次操作之间,别的客户端可能就把本来筹备批改的值给批改了,所以无奈保障隔离性。
b) 而应用 Pipeline 是一次性把所有命令打包好全副发送到服务端,服务端全副解决实现后返回。这么做好的益处,一是缩小了来回网络 IO 次数,进步操作性能。二是一次性发送所有命令到服务端,服务端在处理过程中,是不会被别的申请打断的(Redis 单线程个性,此时别的申请进不来),这自身就保障了隔离性。咱们平时应用的 Redis SDK 在应用开启事务时,个别都会默认开启 Pipeline 的,能够注意察看一下。
集群模式下 Redis 事务如何保障原子性
呈现概率: ★★★
Redis 事务中每个命令都须要发送到服务端, 不过 Redis 事务能够保障命令原子化执行
Redis 事务只能作用于单个节点。集群环境下,执行 Redis 命令时,会依据 key 计算出一个槽位(slot), 而后依据槽位重定向到特定的节点上执行操作。
也欢送关注我的公众号: 散步 coding。一起交换, 在 coding 的世界里散步, 回复: redis, 收费获取最新 Redis 面试题 (含答案)。