2. 进阶
2.1 事务
MULTI 表示开启一个事务;EXEC 执行事务
MULTI
需要执行的语句
EXEC
注意:redis的事务不具备回滚功能
2.1.1 错误处理
(1)语法错误,直接返回错误,错误之前的语句会执行,之后的语句不会执行
(2)运行错误,依然会继续执行
2.1.2 WATCH命令
在一个事务中,只有当所有的事务都依次执行完成后才能得到每个结果的返回值,可是有些情况下需要先获得一条命令的返回值,然后再根据这个值执行下一条命令。
思路:在GET获得键值后,保证该键值不被其他客户端修改,直到函数执行完成后才允许其他客户端修改该键值。
WATCH可以监控一个或多个键,一旦其中有一个键被修改(删除),之后的事务就不会执行,监控一直持续到EXEC命令(事务中的命令是在EXEC之后执行的,所以在MULTI命令后可以修改WATCH监控的键值),如:
提示 由于WATCH命令的作用只是当被监控的键值被修改后阻止之后一个事务的执行,而不能保证其他客户端不修改这一键值,所以我们需要在EXEC执行失败后重新执行整个函数。
执行EXEC命令后会取消对所有键的监控,如果不想执行事务中的命令也可以使用UNWATCH命令来取消监控。
2.2 过期时间
EXPIRE 以秒为单位
PXEPIRE 以毫秒为单位
1. EXPIRE | PEXPIRE 键 过期时间
2. TTL | PTTL 键的剩余时间
3. PERSIST KEY 取消键的过期时间设置
除了PERSIST命令外,使用SET或者GETSET命令为键赋值也会同时清除键的过期时间
设置Redis最大可用内存大小(单位:字节)
修改配置文件的maxmemory参数,当超出这个限制时Redis会依据maxmemory-policy参数指定的策略来删除不需要的键直到Redis占用的内存小于指定内存。
如当maxmemory-policy设置为allkeys-lru时,一旦Redis占用的内存超过了这个限制值,Redis会不断地删除数据库中最近最少使用的键,直到占用的内存小于限制值。如下为从书中摘取的淘汰键的规则。
2.3 SORT命令
SORT命令可以用来排序列表,集合,有序集合;在对有序集合排序时,会忽略元素的分数,只针对元素自身的值进行排序。
1. 排序列表
2. 排序有序集合,只针对元素自身的值进行排序
3. 除了排序数字外,sort命令还可以通过ALPHA参数实现按照字典顺序排序非数字元素
sort命令的DESC参数可以实现将元素按照从大到小的顺序排序;还支持LIMIT参数来返回指定范围的结果,limit offset count,跳过前offset个元素,并获取之后的count个元素
2.3.1 BY参数
SORT的另一个强大参数BY参考键,其中参考键可以是字符串类型键或者散列类型键的某个字段(表示为键名->字段名)
SORT命令的排序将不再依据元素自身的值进行排序,而是对每个元素使用元素的值替换参考键中的第一个“*”,并获取其值,然后依据该值对元素排序。
2.3.2 GET参数
它的作用是使SORT命令的返回结果不再是元素自身的值,而是GET参数中指定的键值;GET参数的规则和BY参数一样,GET参数也支持字符串类型和散列类型的值,并使用“*”作为占位符。
2.3.3 STORE参数
默认情况下SORT会直接返回排序结果,如果希望保存排序结果,可以使用STORE参数。
2.3.4 性能优化
SORT是Redis中最强大最复杂的命令之一,如果使用不好很容易成为性能瓶颈。SORT命令的时间复杂度是O(n+mlog(m)),其中n表示要排序的列表(集合或有序集合)中的元素个数,m表示要返回的元素个数。当n较大的时候SORT命令的性能相对较低,并且Redis在排序前会建立一个长度为n的容器来存储待排序的元素,虽然是一个临时的过程,但如果同时进行较多的大数据量排序操作则会严重影响性能。
所以开发中使用SORT命令时需要注意以下几点。
(1)尽可能减少待排序键中元素的数量(使N尽可能小)。
(2)使用LIMIT参数只获取需要的数据(使M尽可能小)。
(3)如果要排序的数据数量较大,尽可能使用STORE参数将结果缓存。
2.4 消息通知
发布订阅 -> 一般使用专门的MQ,不予介绍,知道Redis有这个功能就行。
2.5 管道
客户端与Redis使用TCP协议连接,在执行多个命令时,每条命令都需要等待上一条命令执行完,即使不需要上一条命令的执行结果。通过管道可以一次性发送多条命令并在执行完后一次性将结果返回,当一组命令中每条命令都不依赖于之前命令的执行结果时就可以将这组命令一起通过管道发出。管道通过减少客户端与Redis的通信次数来实现降低往返时延累计值的目的。
2.6 节省空间
Redis是一个基于内存的数据库,所有数据都存储在内存中,所以如何优化内存,减少内存空间占用对成本控制来说是一个非常重要的话题。
1. 简明键名和键值
如将very.important.person:20改成VIP:20
2. 内部编码优化
Redis为每种数据类型都提供了两种内部编码格式,Redis会根据实际情况自动调整,对开发者透明,如下图。
查看内部编码格式:OBJECT ENCODING KEY