大家好,我是散步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> MULTIOK127.0.0.1:6379> SET name '散步coding'QUEUED127.0.0.1:6379> SET brief '一个专一于算法、数据库、职场的公众号'QUEUED127.0.0.1:6379> GET nameQUEUED127.0.0.1:6379> EXEC1) OK2) OK3) "散步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> MULTIOK
这个命令惟一做的就是, 将客户端的 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> MULTIOK127.0.0.1:6379> SET name "散步coding"QUEUED127.0.0.1:6379> GET nameQUEUED
3)执行事务
当客户端进入事务状态之后, 客户端发送的命令就会被放进事务队列里。
EXEC 、 DISCARD 、 MULTI 和 WATCH 这四个命令 —— 当这四个命令从客户端发送到服务器时, 它们会像客户端处于非事务状态一样, 会被服务器立刻执行。
127.0.0.1:6379> EXEC1) OK2) OK3) "散步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 1OK127.0.0.1:6379>WATCH kOK127.0.0.1:6379>set k 2OK127.0.0.1:6379>MULTIOK127.0.0.1:6379>set k 3QUEUED127.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 100WATCH goods_quantityMULTIif goods_quantity < total_quantity && user_id not in 'user_list' incr goods_quantity set 'user_list' user_idendEXEC
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面试题(含答案)。