- 2021-05-17更新:增加Redis 6.2新增的
LMOVE
、BLMOVE
命令。
在前文中,我们已经介绍了Redis列表相关的LPUSH
、LPOP
等命令。在本文中,我将继续介绍Redis中列表的LTRIM
、RPOPLPUSH
、BLPOP
、BRPOP
、BRPOPLPUSH
、LPOS
以及Redis 6.2新增的LMOVE
以及BLMOVE
命令。
从Redis 6.2.0开始,RPOPLPUSH
以及BRPOPLPUSH
命令将考虑被启用,请分别使用LMOVE
以及BLMOVE
替代。
LTRIM
LTRIM
命令用于对列表进行修建,即只保留指定范围内的部分元素。指定范围的偏移量start
及stop
都为以0为开始,即索引0
为列表中的第一个元素,负数值表示相对于列表队尾的位置(如-1
代表列表中最后一个元素)。例如命令LTRIM mykey 0 4
在执行后只保留列表中的前五个元素,其它元素将被删除。
LTRIM key start stop
当start
的值大于列表的长度或start
大于stop
时,结果将为一个空列表。若stop
大于列表的长度,其值将被设置为列表最后一个元素的索引值。
在Redis文档中提到了使用LTRIM
与LPUSH
或RPUSH
命令配合使用,将达到使列表长度保持在指定大小内的效果,例如执行下述命令时,将使mylist
列表的长度始终保持在100以内(包括100)。
redis> LPUSH mylist someelement
redis> LTRIM mylist 0 99
示例
redis> RPUSH mykey "value1" "value2" "value3" "value4" "value5"
(integer) 5
redis> LTRIM mykey 1 -2
OK
redis> LRANGE mykey 0 -1
1) "value2"
2) "value3"
3) "value4"
处理超出边界的情况:
redis> RPUSH mykey "value1" "value2" "value3" "value4" "value5"
(integer) 5
# stop大于列表大小
redis> LTRIM mykey 2 10
OK
redis> LRANGE mykey 0 -1
1) "value3"
2) "value4"
3) "value5"
# start与stop皆大于列表大小
redis> LTRIM mykey 5 10
OK
redis> LRANGE mykey 0 -1
(empty array)
RPOPLPUSH
RPOPLPUSH
命令用于将source
所指定的列表中队尾位置的元素移除,并插入到destination
所指定的列表队首位置。该命令执行后将返回从source
中移除并插入到destination
中的元素。
RPOPLPUSH source destination
若source
所指定的列表不存在,将返回nil
且不执行其它操作。若destination
所指定的列表不存在,则将创建一个空队列并执行插入操作。
若source
与destination
相同,执行后的结果将为移除队尾的元素并插入到队首。
正如上文提到,从Redis 6.2.0开始RPOPLPUSH
命令将考虑被弃用,请在新的代码实现中使用LMOVE
代替。
示例
# mykey不存在
redis> RPOPLPUSH mykey newkey
(nil)
redis> RPUSH mykey "value1" "value2" "value3"
(integer) 3
redis> RPOPLPUSH mykey newkey
"value3"
redis> LRANGE newkey 0 -1
1) "value3"
redis> LRANGE mykey 0 -1
1) "value1"
2) "value2"
# 源键与目标键相同
redis> RPOPLPUSH mykey mykey
"value2"
redis> LRANGE mykey 0 -1
1) "value2"
2) "value1"
BLPOP / BRPOP
BLPOP
命令是阻塞版的LPOP
,当给定列表中无元素可被弹出时将阻塞连接,直到超时或有元素可被弹出。与LPOP
不同的是,BLPOP
可以给定多个键名,并将依次检查各个列表。若给定的键名中存在至少一个为非空列表,执行BLPOP
将弹出并返回第一个非空列表中的队首元素。
BRPOP
命令与BLPOP
相似,即为阻塞版的RPOP
操作,其与BLPOP
的区别为存在非空列表时将从队尾弹出元素。
BLPOP key [key ...] timeout
BRPOP key [key ...] timeout
BLPOP
/BRPOP
参数中的timeout
为一个以秒为单位的数值,用于表示阻塞的最长时间。当timeout
的值为0
时,表示将无限期地阻塞,直到有元素可被弹出。
BLPOP
/BRPOP
命令执行后将返回一个数组,其第一个元素为键名,第二个元素为被弹出的元素。当列表直到超时也无元素可被弹出时,返回nil
。
关于更多有关BLPOP
/BRPOP
命令的介绍,例如当使用LPUSH
插入多个元素时或在MULTI
/EXEC
事务中的行为,可以参考BLPOP
文档。
示例
redis> BLPOP mykey 10
# 等待10秒后
(nil)
redis> RPUSH mykey "value1" "value2" "value3"
(integer) 3
redis> BLPOP mykey 10
1) "mykey"
2) "value1"
在执行BLPOP
/BRPOP
后在超时时间内在通过另外的客户端连接往列表中插入元素,示例中使用redis1
与redis2
来区分不同的客户端连接:
redis1> BLPOP mykey 10
# redis2> LPUSH mykey "value"
# (integer) 1
1) "mykey"
2) "value"
给定的列表中存在非空列表:
# redis> LPUSH key2 "value2"
# redis> LPUSH key3 "value3"
redis> BRPOP key1 key2 key3 10
1) "key2"
2) "value2"
给定的列表中均为空列表,连接将被阻塞直到任一列表中插入元素:
redis1> BLPOP key1 key2 key3 10
# redis2> LPUSH key2 "value2"
# (integer) 1
1) "key2"
2) "value2"
示例中主要演示了BLPOP
命令,除弹出的元素为队尾元素外,BRPOP
与BLPOP
没有较大的区别。
BRPOPLPUSH
BRPOPLPUSH
命令即阻塞版的RPOPLPUSH
命令,当source
指定的列表不为空时(列表中存在元素),其行为与RPOPLPUSH
命令相同。
BRPOPLPUSH source destination timeout
若执行命令时列表不为空,执行操作后返回与RPOPLPUSH
命令相同。若等待超时(在timeout
时间内无元素可被弹出),则将返回nil
及等待的时间。若在等待期间存在元素可被弹出,则在执行操作后返回一个数组,其中包括被弹出元素的值及等待的时间。
关于更多的信息,可参考RPOPLPUSH
。
正如上文提到,从Redis 6.2.0开始BRPOPLPUSH
命令将考虑被弃用,请在新的代码实现中使用BLMOVE
代替。
示例
redis> BRPOPLPUSH mykey newkey 10
# 等待10秒后
(nil)
(10.08s)
redis> RPUSH mykey "value1" "value2" "value3"
(integer) 3
redis> BRPOPLPUSH mykey newkey
"value3"
redis> LRANGE mykey 0 -1
1) "value1"
2) "value2"
redis> LRANGE newkey 0 -1
1) "value3"
当给定源列表为空时,将阻塞连接直到有元素可被弹出:
redis1> BRPOPLPUSH mykey newkey 10
# redis2> LPUSH mykey "value"
# (integer) 1
"value"
(2.34s)
redis1> LRANGE newkey 0 -1
1) "value"
redis1> LRANGE mykey
(empty array)
LPOS
LPOS
命令返回列表中符合条件的元素的索引,返回的索引从0
开始(即0
为列表中的第一个元素。在未指定参数的情况下,默认从列表的队首开始扫描,直到找到符合的元素。
LPOS key element [RANK rank] [COUNT num-matches] [MAXLEN len]
LPOS
有三个可选参数RANK
、COUNT
以及MAXLEN
:
RANK
获取第N个符合条件元素;COUNT
获取的元素数量;MAXLEN
只比较给定数量的元素。
LPOS
现还未在stable版本中被添加(预计在6.0.6版本中被添加),我们仅对其作简单的介绍,若有兴趣对其深入了解,可参考LPOS文档。
示例
redis> RPUSH mykey "value1" "value2" "value3" "value4" "value5"
(integer) 5
redis> LPOS mykey "value3"
(integer) 2
redis> LPOS mykey "value6"
(nil)
使用RANK
及COUNT
参数实现较为复杂的查询操作:
redis> RPUSH mykey "value1" "value2" "value3" "value1" "value3" "value1"
(integer) 6
# 获取第二个符合的元素
redis> LPOS mykey "value1" RANK 2
(integer) 3
# 获取前两个符合的元素
redis> LPOS mykey "value1" COUNT 2
1) (integer) 0
2) (integer) 3
# 从第二个符合的元素开始获取两个符合的元素
redis> LPOS mykey "value1" RANK 2 COUNT 2
1) (integer) 3
2) (integer) 5
使用MAXLEN
参数限定检查的最大数量:
redis> RPUSH mykey "value1" "value2" "value3" "value1" "value3" "value1"
(integer) 6
redis> LPOS mykey "value1" COUNT 5 MAXLEN 4
1) (integer) 0
2) (integer) 3
LMOVE / BLMOVE
LMOVE
是Redis 6.2.0中新增的命令,用于将源队列中首/尾元素插入到目标队列的队首/队尾位置,并返回从源队列中弹出并压入到目标队列中的元素。若源队列不存在,将返回nil
,且不会插入任何元素到目标队列中。若源队列与目标队列为相同队列,该操作将只在该队列中进行。
LMOVE source destination LEFT|RIGHT LEFT|RIGHT
LMOVE
命令将被用于替代RPOPLPUSH
命令,RPOPLPUSH
命令等同于LMOVE RIGHT LEFT
。
BLMOVE
是LMOVE
命令的阻塞版本,当源队列不为空时效果与LMOVE
相同。当源队列为空时将等待timeout
参数所指定的时间。同样,若timeout
参数的值设置为0
则为持续等待。
BLMOVE source destination LEFT|RIGHT LEFT|RIGHT timeout
示例
redis> RPUSH list1 1 2 3 4 5
(integer) 5
redis> RPUSH list2 6 7
(integer) 2
redis> LMOVE list1 list2 LEFT RIGHT
"1"
redis> LRANGE list1 0 -1
1) "2"
2) "3"
3) "4"
4) "5"
redis> LRANGE list2 0 -1
1) "6"
2) "7"
3) "1"
结束语
我们已经介绍了字符串、列表以及键值对操作的一些命令。在后续的文章中,我们将继续介绍哈希以及集合类型的相关命令。