一、事务
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数据库获取数据,可以通过管道执行该操作。管道可以将多条对数据库的操作一次性的发送个服务端,获取数据减少耗时。