关于redis:2022年Redis最新面试题第3篇-Redis事务

37次阅读

共计 3783 个字符,预计需要花费 10 分钟才能阅读完成。

大家好,我是散步 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 面试题 (含答案)。

正文完
 0