Redis学习笔记---进阶篇
本文最后更新于:2022年4月1日 上午
一、事务
1.MULTI命令
Redis中的事务( transaction
)是一组命令的集合。一个事务中的命令要么都执行,要么都不执行。Redis通过 MULTI
开启事务,之后的命令将被存储在等待执行的事务队列中,使用 EXEC
命令将等待执行的事务队列中的所有命令按照发送顺序依次执行。EXEC
命令的返回值就是这些命令的返回值组成的列表。返回值顺序和命令的顺序相同。
1 |
|
2.错误处理
a. 语法错误。指命令不存在或者命令参数的个数不对。只要有一个命令有语法错误,执行 EXEC
命令之后Redis就会直接返回错误,连语法正确的命令也不会执行。
1 |
|
b. 运行错误。如果事务里的一条命令出现了运行错误,事务里其他的命令依然会继续执行。
1 |
|
Redis的事务没有关系数据库事务提供的回滚(
rollback
)功能。
3.WATCH命令
watch
命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不执行。监控一直持续到 EXEC
命令。
1 |
|
执行 EXEC
命令后会取消对所有键的监控,如果不想执行事务中的命令也可以使用 UNWATCH
命令来取消监控。
二、过期时间
1.EXPIRE命令
使用 expire
命令设置一个键的过期时间,到时间后Redis会自动删除它。
EXPIRE
命令的使用方法为 EXPIRE key seconds
,其中 seconds
参数表示为键的过期时间,单位为 秒
。
EXPIRE
命令返回 1
表示设置成功,返回 0
则表示键不存在或设置失败。
TTL
命令可以查看一个键还有多少时间会被删除。当键不存在时 TTL
命令返回 -2
;没有为键设置过期时间返回为 -1
.
1 |
|
PERSIST
命令可以取消键的过期时间(即将键恢复成永久的)。如果过期时间被成功清除,则返回 1
,否则返回 0
.
1 |
|
使用 set
或 getset
命令为键赋值也会同时清除键的过期时间。
EXPIRE
命令的seconds
参数必须是整数,最小单位是1
秒。PEXPIRE
命令可以设置更精确的过期时间,最小单位是1
毫秒,可以使用PTTL
命令以毫秒为单位返回键的剩余时间。
2.缓存
通过修改配置文件 /usr/local/etc/redis.conf
(mac系统,通过 homebrew
安装的Redis)的 maxmemory
参数,限制Redis最大可用内存大小(单位是字节),当超出这个限制时Redis会根据 maxmemory-policy
参数指定的策略来删除不需要的键直到Redis占用的内存小于指定内存。默认的策略是 noeviction
。
maxmemory-policy
支持的规则:
volatile-lru
:使用LRU算法删除一个键(只对设置了过期时间的键)
allkeys-lru
:使用LRU算法删除一个键
volatile-random
:随机删除一个键(只对设置了过期时间)
allkeys-random
:随机删除一个键
volatile-ttl
:删除过期时间最近的一个键
noeviction
:不删除键,只返回错误
三、排序
1.有序集合的集合操作
有序集合的操作是将运算结果存入新的键中,以便后续处理。比如 zinterstore
、zunionstore
等操作。如果需要直接获取运算结果,可以使用 multi
、zinterstore
、zrange
、del
和 exec
等命令自己实现。
1 |
|
2.SORT命令
sort
命令可以对列表类型、集合类型和有序集合类型键进行排序。
1 |
|
在对有序集合类型排序时会忽略元素的分数,只针对元素自身的值进行排序。
1 |
|
除了可以对数字排列外,还可以通过 ALPHA
参数实现按照字典顺序排列非数字元素。
sort默认是按从小到大的顺序排列,通过 DESC
参数可以实现将元素按照从大到小的顺序排列。LIMIT
参数返回指定范围的结果。
1 |
|
3.BY参数
语法为 BY 参考键,参考键可以是字符串类型键或者是散列类型键的某个字段(表示为键名->字段名)
如果提供了 BY
参数,sort
命令将不再依据元素自身的值进行排序,而是对每个元素使用元素的值替换参考键中的第一个 *
并获取其值,然后依据该值对元素排序。
1 |
|
当参考键名不包含 *
时(即常量键名,与元素值无关),sort
命令将不会执行排序操作。
如果几个元素的参考键值相同,则sort命令会再比较元素本身的值来决定元素的顺序。
当某个元素的参考键不存在时,会默认参考键值的值为 0
.
4.GET参数
get
参数不影响排序,他的作用是使 sort
命令的返回结果不再是元素自身的值,而是 GET
参数中指定的键值。get
参数也支持字符串类型和散列类型的键,并使用 *
作为占位符。有 N
个get参数,每个元素返回的结果就有 N
行。
1 |
|
get # 会返回元素本身的值
5.STORE参数
默认下 SORT
会直接返回排序结果,如果希望保存排序结果,可以使用 STORE
参数。保存后的键的类型为列表类型,如果键已经存在则会覆盖它。加上 store
参数后 sort
命令返回的是结果的个数。
1 |
|
STORE
参数常用来结合EXPIRE
命令缓存排序结果。
6.性能优化
SORT
命令的时间复杂度是O(n+mlog(m)),其中 n
表示要排序的列表中的元素个数,m
表示要返回的元素个数。
使用 SORT
命令时需注意几点:
①尽可能减少待排序键中元素的数量(使N尽可能小)。
②使用 LIMIT
参数只获取需要的数据(使M尽可能小)。
③如果要排序的数据数量较大,尽可能使用 STORE
参数将结果缓存。
四、消息通知
1.任务队列
使用任务队列的好处:
①松耦合:生产者和消费者无需知道彼此的实现细节,只需要约定好任务的描述格式。
②易于扩展:消费者可以有多个,而且可以分布在不同服务器中,也能降低单台服务器的负载。
2.使用Redis实现任务队列
通过使用 LPUSH
和 RPOP
命令就可实现队列的概念。如果要实现任务队列,只需要让生产者将任务使用 LPUSH
命令加入到某个键中,另一个边让消费者不断地使用 RPOP
命令从改建中取出任务即可。
BRPOP
命令与 RPOP
命令相似,区别在于当列表中没有元素时 BRPOP
命令会一直阻塞住连接,直到有新的元素加入。
BRPOP
命令接收两个参数:第一个是键名,第二个是超时时间,单位是秒,当超过此时间仍然没有获得新元素的话就会返回 nil
。超时时间为 0
,表示不限制等待时间,即如果没有新元素加入列表就会永远阻塞下去。
3.队列优先级
BRPOP
命令可以同时接收多个键,意义是同时检测多个键,如果所有键都没有元素则阻塞,如果其中有一个键有元素则会从该键中弹出元素。
如果多个建都有元素则按照从左到右的顺序取第一个键中的一个元素。
4.”发布/订阅”模式
”发布/订阅“模式中包含两种角色,分别是 发布者
和 订阅者
。订阅者可以订阅一个或若干个频道( channel
),而发布者可以向指定的频道发送消息,所有订阅此频道的订阅者都会收到此消息。
发布者发布消息的命令是
PUBLISH
,用法是PUBLISH channel message
。发出去的消息不会被持久化,也就是说当有客户端订阅channel后只能收到后续发布到该频道的消息,之前发送的就收不到了。订阅频道的命令是
SUBSCRIBE
,可以同时订阅多个频道,用法是SUBSCRIBE channel [channel…]
。UNSUBSCRIBE
命令可以取消订阅指定的频道,如果不指定频道则会取消订阅所有频道。
5.按照规则订阅
使用 PSUBSCRIBE
命令可以订阅指定的规则。
PUNSUBSCRIBE
命令可以退订指定的规则,如果没有参数则会退订所有规则。
使用
PUNSUBSCRIBE
命令只能退订通过PSUBSCRIBE
命令订阅的规则,不会影响直接通过SUBSCRIBE
命令订阅的频道。UNSUBSCRIBE
命令也不会影响通过PSUBSCRIBE
命令订阅的规则。
五、管道
不管是客户端向Redis发送命令还是Redis向客户端返回命令的执行结果,都需要经过网络传输,这两个部分的总耗时称为往返时延。
Redis的底层通信协议对管道( pipelining
)提供了支持。通过管道可以一次性发送多条命令并在执行完后一次性将结果返回,当一组命令中每条命令都不依赖于之前命令的执行结果时就可以将这组命令一起通过管道发出。管道通过减少客户端与Redis的通信次数来实现降低往返时延累计值的目的。
六、节省空间
1.精简键名和键值
2.内部编码优化
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!