加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网_ASP源码网 (https://www.1asp.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

详解Redis基

发布时间:2018-11-14 02:46:18 所属栏目:建站 来源:kelgon
导读:副标题#e# 本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍。之后概览Redis提供的高级能力,并在部署、维护、性能调优等多个方面进行更深入的介绍和指导。 本文适合使用Redis的普通开发人员,以及对Redis进

然而,如果客户端要连续执行的多次操作无法通过Redis命令组合在一起,例如:

  1. SET a "abc"  
  2. INCR b  
  3. HSET c name "hi" 

此时便可以使用Redis提供的pipelining功能来实现在一次交互中执行多条命令。

使用pipelining时,只需要从客户端一次向Redis发送多条命令(以rn)分隔,Redis就会依次执行这些命令,并且把每个命令的返回按顺序组装在一起一次返回,比如:

  1. $ (printf "PINGrnPINGrnPINGrn"; sleep 1) | nc localhost 6379  
  2. +PONG  
  3. +PONG  
  4. +PONG 

大部分的Redis客户端都对Pipelining提供支持,所以开发者通常并不需要自己手工拼装命令列表。

Pipelining的局限性

Pipelining只能用于执行连续且无相关性的命令,当某个命令的生成需要依赖于前一个命令的返回时,就无法使用Pipelining了。

通过Scripting功能,可以规避这一局限性

事务与Scripting

Pipelining能够让Redis在一次交互中处理多条命令,然而在一些场景下,我们可能需要在此基础上确保这一组命令是连续执行的。

比如获取当前累计的PV数并将其清0

  1. > GET vCount  
  2. 12384  
  3. > SET vCount 0  
  4. OK 

如果在GET和SET命令之间插进来一个INCR vCount,就会使客户端拿到的vCount不准确。

Redis的事务可以确保复数命令执行时的原子性。也就是说Redis能够保证:一个事务中的一组命令是绝对连续执行的,在这些命令执行完成之前,绝对不会有来自于其他连接的其他命令插进去执行。

通过MULTI和EXEC命令来把这两个命令加入一个事务中:

  1. > MULTI  
  2. OK  
  3. > GET vCount  
  4. QUEUED  
  5. > SET vCount 0  
  6. QUEUED  
  7. > EXEC  
  8. 1) 12384  
  9. 2) OK 

Redis在接收到MULTI命令后便会开启一个事务,这之后的所有读写命令都会保存在队列中但并不执行,直到接收到EXEC命令后,Redis会把队列中的所有命令连续顺序执行,并以数组形式返回每个命令的返回结果。

可以使用DISCARD命令放弃当前的事务,将保存的命令队列清空。

需要注意的是,Redis事务不支持回滚:

如果一个事务中的命令出现了语法错误,大部分客户端驱动会返回错误,2.6.5版本以上的Redis也会在执行EXEC时检查队列中的命令是否存在语法错误,如果存在,则会自动放弃事务并返回错误。

但如果一个事务中的命令有非语法类的错误(比如对String执行HSET操作),无论客户端驱动还是Redis都无法在真正执行这条命令之前发现,所以事务中的所有命令仍然会被依次执行。在这种情况下,会出现一个事务中部分命令成功部分命令失败的情况,然而与RDBMS不同,Redis不提供事务回滚的功能,所以只能通过其他方法进行数据的回滚。

通过事务实现CAS

Redis提供了WATCH命令与事务搭配使用,实现CAS乐观锁的机制。

假设要实现将某个商品的状态改为已售:

  1. if(exec(HGET stock:1001 state) == "in stock") 
  2.  
  3. exec(HSET stock:1001 state "sold"); 

这一伪代码执行时,无法确保并发安全性,有可能多个客户端都获取到了”in stock”的状态,导致一个库存被售卖多次。

使用WATCH命令和事务可以解决这一问题:

  1. exec(WATCH stock:1001);  
  2. if(exec(HGET stock:1001 state) == "in stock") {  
  3. exec(MULTI);  
  4. exec(HSET stock:1001 state "sold");  
  5. exec(EXEC);  

(编辑:安卓应用网_ASP源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读