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 协议 ,转载请注明出处!