redis入门指南一书总结下(redis进阶)

来源:互联网 发布:mv视频制作软件 编辑:程序博客网 时间:2024/05/22 07:57

redis事务

Redis中的事务是一组命令的集合,事务和命令一样都是Redis的最小执行单位
事务的原理为:先发送MULTI命令告诉redis接下来将会开启一个事务,然后发送一系列命令,最后发送执行命令EXEC告诉redis执行这一系列命令。如下就是一个简单的事务处理:

这里写图片描述

事务通常可以用来保证数据的安全,如果在发送exec命令前客户端断线了,那么redis将会清空事务队列,事务中的所有命令都不会执行。而一旦客户端发送了exec命令,即使之后客户端断线了也不会影响事务的执行,因为redis已经记录了所有要执行的命令
如果事务中的语句发生错误,那么redis将会如何处理呢?首先,我们需要知道是什么原因导致的错误,主要有两种情况:
1.语法错误:命令不存在或者参数的个数不对,只要在事务中存在一个语句出现了语法的错误,那么所有的命令都不会执行,如下:

这里写图片描述

2.运行错误:运行错误指在命令执行时出现的错误,比如使用散列类型的命令操作集合类型的键值时,在语法上是没有错误的,然而在运行起来时就会出错,看如下:

这里写图片描述

这里需要注意的一点是:redis的事务和大多数的事务不同,它没有提供rollback回滚操作,想要复原到事务执行之前需要自己进行元素的设置操作来手动实现
有时候对于事务处于安全考虑,我们想要实现这样一个情况:在事务执行之前如果某个键值发生了改变就不执行事务。要实现这样一个情况就需要使用到另一个强大的命令watch该命令可以监控一个或者多个键,一旦在接下来的事务执行之前有一个键值发生了改变,那么事务就不会执行。这里需要注意的是:这里所指的事务是接下来的第一个,而不是所有的。看如下:

这里写图片描述

我们发现,最终事务的执行结果为(nil),也就是redis中的null,因为在该事物执行之前进行了testkey的修改,所以接下来的事务将不会执行。如果想要取消监视,可以使用命令unwatch,不过该命令只能取消所有的监视,而不能取消指定键的监视


生存时间

在实际的开发中经常会遇到一些有时效的数据,比如设计一个限时活动的时候,数据库中存储的一些还未使用优惠券等过了优惠的时间就需要删除这些数据。对于关系数据库比如MySQL之类的一般需要手动删除或者额外添加一个字段保存到期时间,然后定期检测删除过期数据。而对于redis来说, 这一操作就变得简单了许多
在redis中,可以使用命令expire来设置一个键的生存时间,到指定时间后redis就会自动删除它,它的命令格式为:redis> EXPIRE key seconds其中seconds表示键的生存时间,单位是秒

这里写图片描述

如果想要设置更精确的生存时间可以通过expireat命令,它的命令格式和expire一样,只是第二个参数的单位不是秒,而是unix时间戳
想要查看指定键当前的剩余生存时间,可以使用命令ttl

这里写图片描述

在这里使用命令expire设置键值的生存时间时需要注意:我们之前说到的watch命令监视键,如果正在被监视的键因为生存时间到期被自动删除这一修改不会被watch命令认为该键被改变


排序

在前面一篇博客提到redis数据类型时,有一个有序集合类型,它里面的元素是有序的,而对于其余的数据类型该如何进行排序呢?
我们可以借助redis提供的sort命令来对数据进行排序,该命令可以对列表类型、集合类型和有序集合类型进行键值排序,其中对有序集合类型的键值排序的方式同样是通过元素自身的值进行排序的,而不是有序集合类型自带的分数排序

这里写图片描述

sort命令默认只会对数值类型进行排序,如果元素值为非数值类型,结果就会报错,因为redis无法自动将数值类型与字符串类型进行比较,需要我们手动添加参数ALPHA来实现按照字典顺序进行排列
redis> SORT key ALPHA
sort命令默认是按照升序进行排列的,我们可以添加DESC参数来实现按照降序进行排列输出结果
redis> SORT key DESC
sort命令默认是按照元素自身的值进行排序的,如果想要根据其他对应的键值进行排序,可以添加by参数,如下图

这里写图片描述

由上图可知,我们通过获取集合set中的每一个元素值,并通过demo.*进行逐个元素值注入并根据demo.*对应的值进行比较然后升序输出,最终输出的结果依旧是原来的set集合的值,而不是demo对应的值
sort命令默认是返回集合中的元素的值,如果想要返回指定的键值,比如上面的demo对应的值,可以通过get参数来指定,其命令格式和by一样

这里写图片描述

对于get参数,如果想要返回元素本身的值可以使用#,当然大多数时候是没有必要的
sort命令默认是直接将结果输出,如果想要保存结果到指定变量中,可以使用store参数,其后指定一个键名或者说字段即可,不管是否存在都行
性能优化:SORT命令是redis最强大也是最复杂的命令之一,该命令的时间复杂度与集合本身元素数量和要返回的元素数量有关,当集合本身元素数量过多或者返回的数量过多时SORT的性能较低,并且redis在使用该命令进行排序前会先建立一个长度为n(集合本身元素数量)的容器来存储待排序的元素,虽然是一个临时过程,但是同时进行的话也会严重影响性能


消息通知

前面我们提到过从列表中弹出元素使用的是命令LPOP/RPOP,该命令是非阻塞式命令,如果有元素则弹出并返回该元素的值,如果没有则输出(nil),而其实还有一个相对应的比较强大的阻塞时弹出命令:BRPOP
该命令和RPOP命令的唯一区别在于:如果列表中没有元素则该命令会一直阻塞下去,知道有元素就弹出并返回该元素
我们可以使用该命令来模拟实现一些简单的消息通知行为,该命令的格式为:BRPOP key1 key2 key3,可以同时指定多个列表类型元素,其中如果都没有元素则会阻塞,从而可以实现任务的优先级:优先执行的任务可以放在前面


发布/订阅模式

redis提供了一组命令用于简单实现redis客户端之间的通信,对应命令为:PUBLISH发布和SUBSCRIBE订阅,对应的命令格式如下:
//发布客户端发布消息redis> PUBLISH channer info//订阅客户端接收订阅消息redis> SUBSCRIBE channer
其中channer表示订阅的频道,它可以看成是一个变量,使用示例看下图

这里写图片描述

原创粉丝点击