一、事务

1、事务的实现

(1)事务的概述:

  事务如同原子操作,要么全部执行,要么全部不执行。在redis数据库中事务会将命令组合一同发送给数据库服务去执行,但是redis数据库的事务没有回滚机制。

(2)事务的执行命令:

  MULTI

  操作数据命令1

  .....

  操作数据命令n

  EXEC

  

2、事务的错误处理

  (1)如果事务中的某条指令出现语法错误,所有存在于事务中的命令将不会执行

  (2)如果事务中使用的操作数据的指令出现混乱,如操作列表的指令去执行集合,此时redis数据库无法识别,会接收该事务的执行。

    因此在使用事务的时候一定要慎重。

3、防止竞态

  事务的操作中的每条指令执行的结果只能最后返回,所以前一条指令的执行结果不能作为后一条命令的参数。由于事务的这一特点,需要防止在获取数据后,其他客户端对该数据进行修改,导致下一条命令执行时出现脏数据的现象,redis数据库引入了监控机制。监控机制的指令:WATCH。只要引入监控机制,说明该键值已经被监控,其他客户端对该键值的修改,都会导致对该键操作的事务无法执行。同时对键值的监控只有在执行事务的EXEC指令后才会消失。

  监控操作:

  SET foo 123

  WATCH  foo

  SET foo 234

  MULTI

  SET foo 345

  EXEC

  该事务将无法执行,由于在对键值监控后,对该键值进行了修改,事务会退出执行。

二、过期时间

1、命令介绍

  由于在现实生活中会遇到一些具有时效性的数据,例如显示优惠活动,缓存和验证码等,一旦超过期限,需要对数据进行删除操作。在其他数据库中可能会借助前端代码进行删除操作,但是在Redis数据库中具有超过一定期限自动删除机制。过期时间的设置分为秒和毫秒的设置。

  设置秒过期时间:

  EXPIRE foo 900     //设置foo键的期限是900秒

  设置毫秒级的过期时间:

  PEXPIRE foo   900    //设置foo键的期限是900毫秒

  撤销键的过期时间:

  PERSIST foo    //取消foo键的过期时间

  查看键的期限:

  TTL  foo    //查看foo键的过期时间

  注意:除了PERSIST命令可以取消键值的过期时间,可以通过SET指令取消键值的过期时间。

2、实现访问频率限制

 在显示生活中可能会遇到这样一种场景,对某一个功能不能点击的太过频繁,一旦超出一定的点击数就会对永辉作出详细的提示,这一场景可以通过使用过期时间进行限制,对键值的时间设置为一定的时间,在该段时间内点击次数不能超过100次。超过一百次就会作出相应的提示。在键值过期之后,清除该键,重新对其设置。 

3、实现缓存

  在显示生活中会遇到这样一种场景:学校获取前十名的学生成绩,这十名学生是在不断变化的,同时为了提高获取的效率,需要将学生的信息放入缓存,但是缓存的大小是有限制的。因此需要对该键进行过期时间的设置。

三、排序

1、升序与降序

  有序集合(sorted set)可以帮助我们存储具有一定顺序的数据。但是我们也可以借助Redis数据库的SORT命令进行查询。操作如下:

  redis 127.0.0.1:6379> lpush mylist 23  

  (integer) 1  

  redis 127.0.0.1:6379> lpush mylist 15  

  (integer) 1  

  redis 127.0.0.1:6379> lpush mylist 50   

  (integer) 1  

  redis 127.0.0.1:6379> lpush mylist 7   

  (integer) 1  

  redis 127.0.0.1:6379> sort mylist  

  1) "7"   

  2) "15"   

  3) "23"   

  4) "50"   

  可以使用DESC降序或者ASC升序进行标注

  操作指令:

  SORT   键名   DESC/ASC

2、限制查询个数

  并不是所有的数据都要查询出来,很多场景只需要部分数据,查询部分数据的操作指令:

  SORT  键名  DESC/ASC   LIMIT   标识1  标识2

3、按照指定字段查询

  在查询时,可以按照指定的字段进行升序或降序进行排序:

  redis 127.0.0.1:6379> SORT  mylist  BY  post:*>time DESC

  该操作的意思是,mylist中的值会作为键名替换掉*,对参考键post下的键按照time字段进行排序,返回结果为mylist键中的值。参考键可以是字符串或者散列键。字符串形式的如下所示

  redis 127.0.0.1:6379> LPUSH  mylist  2     1    3

  redis 127.0.0.1:6379> SET  post:1 50

  redis 127.0.0.1:6379>SET  post:2 100

  redis 127.0.0.1:6379> SET  post:3  -10

  redis 127.0.0.1:6379> SORT  mylist  BY  post:* DESC

4、映射查询

  在查询时并不是所有的返回结果都是我们想要的,或许我们只会保留一部分数据,这是映射查询就会碰上用场。GET指令可以帮助我们获取键值中的指定字段。举例如下:

  redis 127.0.0.1:6379> SORT  mylist  BY  post:*>time DESC   GET  post:*>title

  获取post:*键下的title字段,如果获取多个字段,使用如下格式:

  redis 127.0.0.1:6379> SORT  键名后缀列表键  BY  键名前缀:*>排序字段  DESC  GET  字段1 ......  字段n  

5、保存查询结果

  如果希望将查询的结果进行保存,可以使用STORE命令,举例如下:

  redis 127.0.0.1:6379> SORT  mylist  BY  post:*>time DESC   GET  post:*>title   #  STORE sort.sult   

  该操作的意思是,将排序后查询出的title字段存储到sort.sult键下,以列表的形式保存。

四、消息通知

1、任务队列

  任务队列是通过LPUSH和RPOP指令实现的,在任务队列中生产者只需通过LPUSH指令将任务添加到队列中,消费者就可以通过RPOP指令从队列中获取任务进行消费。只是RPOP指令需要随时执行进行获取队列中的任务。而BRPOP指令可以一直阻塞队列,直到队列中有任务。操作如下:

  BRPOP    queue   0   //从队列queue中获取任务,0表示没有设置超时时间,一旦该参数非零,超过该时间,队列返回nil参数

  格式如下:

  BRPOP   queuename   seconds  

  参数seconds为0,表示如果队列无任务,该指令一直阻塞下去。如果非0,超过该时间,返回结果为nill

2、优先级队列

  在显示生活中可能会有多个任务去执行,但是一旦任务量巨大,可能有部分需要立即执行的任务由于位置较落后,需要等待较长一段时间,需要设置多个队列,并标识队列的优先级。保证优先级高的先执行。

  BRPOP    queue1   queue2   queue3  0

  该格式的说明,只要queue1队列中有任务,先BRPOP出queue1中的任务,然后再BRPOP出queue2和queue3中的任务。

3、发布/订阅模式

  发布/订阅模式主要包括发布者和订阅者,一个订阅者可以订阅多个频道,多个订阅者可以订阅同一个频道。发布者可以向指定的频道发布消息。

  发布格式:

  PUBLISH   channelname

  订阅格式:

  SUBSCRIBE  channelname

  取消订阅模式:

  UNSUBSCRIBE  channelname

  在客户端执行订阅模式之后,除了能够执行订阅模式的命令之外,其他命令禁止使用。

4、按照规则订阅

  模糊订阅格式:

  PSUBSCRIBE  channel?*      //?标识一个字符,*标识0个或者多个字符

  取消模糊订阅:

  PUNSUBSCRIBE  channel?*

五、管道

     在通过客户端向reids数据库获取数据时,由于需要经过网络传输,从而产生往返时延。虽然执行一条指令的往返时延较小,如果有多条命令执行产生的往返时延可能会影响系统性能。当某一功能需要有多条指令从redis数据库获取数据,可以通过管道执行该操作。管道可以将多条对数据库的操作一次性的发送个服务端,获取数据减少耗时。