redis(3)—— 列表
1. 介绍
Redis 列表(List )是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
2. 练习
2.1 LPUSH、RPUSH
将一个或多个值 value 插入到列表 key 的表头、表尾
# 加入单个元素
127.0.0.1:6379> LPUSH lxxm java
(integer) 1
127.0.0.1:6379> get lxxm
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> lget lxxm
(error) ERR unknown command 'lget'
# 加入重复元素
127.0.0.1:6379> lpush lxxm java
(integer) 2
127.0.0.1:6379> lrange lxxm 0 -1
1) "java"
2) "java"
# 一次加入多个元素
127.0.0.1:6379> lpush lxxm redis mybatis xml
(integer) 5
127.0.0.1:6379> lrange lxxm 0 -1
1) "xml"
2) "mybatis"
3) "redis"
4) "java"
5) "java"
2.2 LPUSHX、RPUSHX
将值 value 插入到列表 key 的表头,当且仅当 key 存在并且是一个列表。 和 LPUSH key value [value …] 命令相反,当 key 不存在时, LPUSHX 命令什么也不做
# 对空列表进行 LPUSHX
127.0.0.1:6379> llen xxme
(integer) 0
127.0.0.1:6379> lpushx xxme java
(integer) 0
127.0.0.1:6379> llen xxme
(integer) 0
# 对非空列表进行 LPUSHX
127.0.0.1:6379> llen xxme
(integer) 0
127.0.0.1:6379> lpush xxme java
(integer) 1
127.0.0.1:6379> lpushx xxme java1.8
(integer) 2
127.0.0.1:6379> lrange xxme 0 -1
1) "java1.8"
2) "java"
2.3 LPOP、RPOP
移除并返回列表 key 的头元素、尾部元素
127.0.0.1:6379> lrange lxxm 0 -1
1) "xml"
2) "mybatis"
3) "redis"
4) "java"
5) "java"
127.0.0.1:6379> lpop lxxm #移除头元素
"xml"
127.0.0.1:6379> lrange lxxm 0 -1
1) "mybatis"
2) "redis"
3) "java"
4) "java"
127.0.0.1:6379> rpop lxxm #移除尾元素
"java"
127.0.0.1:6379> lrange lxxm 0 -1
1) "mybatis"
2) "redis"
3) "java"
2.4 RPOPLPUSH
在一个原子时间内,执行以下两个动作:将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。
# source 和 destination 不同
127.0.0.1:6379> lrange lxxm 0 -1
1) "mybatis"
2) "redis"
3) "java"
127.0.0.1:6379> rpoplpush lxxm xxm2
"java"
127.0.0.1:6379> lrange lxxm 0 -1
1) "mybatis"
2) "redis"
127.0.0.1:6379> lrange xxm2 0 -1
1) "java"
# source 和 destination 相同
127.0.0.1:6379> lrange lxxm 0 -1
1) "java"
2) "mybatis"
3) "redis"
127.0.0.1:6379> rpoplpush lxxm lxxm
"redis"
127.0.0.1:6379> lrange lxxm 0 -1
1) "redis"
2) "java"
3) "mybatis"
2.5 lrem
根据参数 count 的值,移除列表中与参数 value 相等的元素。
- count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
- count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
- count = 0 : 移除表中所有与 value 相等的值。
127.0.0.1:6379> lrange xxmlpush 0 -1
1) "java"
2) "python"
3) "java"
4) "json"
5) "sql"
6) "java"
127.0.0.1:6379> lrem xxmlpush -2 java
(integer) 2
127.0.0.1:6379> lrange xxmlpush 0 -1
1) "java"
2) "python"
3) "json"
4) "sql" #最后2个 java 被移除了
2.6 llen
返回列表 key 的长度
# 空列表
127.0.0.1:6379> llen empty
(integer) 0
# 非空列表
127.0.0.1:6379> lrange lxxm 0 -1
1) "java"
2) "json"
3) "python"
4) "redis"
5) "mybatis"
127.0.0.1:6379> llen lxxm
(integer) 5
2.7 LINSERT
LINSERT key BEFORE|AFTER pivot value
将值 value 插入到列表 key 当中,位于值 pivot 之前或之后。
- 将值 value 插入到列表 key 当中,位于值 pivot 之前或之后。
- 当 pivot 不存在于列表 key 时,不执行任何操作。
- 当 key 不存在时, key 被视为空列表,不执行任何操作。
#在 pivot 左侧插入
127.0.0.1:6379> lrange lxxm 0 -1
1) "java"
2) "json"
3) "python"
4) "redis"
5) "mybatis"
127.0.0.1:6379> linsert lxxm before json maven
(integer) 6
127.0.0.1:6379> lrange lxxm 0 -1
1) "java"
2) "maven"
3) "json"
4) "python"
5) "redis"
6) "mybatis"
# pivot 不存在
127.0.0.1:6379> linsert lxxm before jvm jdk
(integer) -1
127.0.0.1:6379> lrange lxxm 0 -1
1) "java"
2) "maven"
3) "json"
4) "python"
5) "redis"
6) "mybatis" #pivot不存在,不会执行插入操作
# key 不存在
127.0.0.1:6379> exists empty
(integer) 0
127.0.0.1:6379> linsert empty before 1st 2nd
(integer) 0
127.0.0.1:6379> exists empty
(integer) 0 # key不存在,插入操作未执行
2.8 LSET
将列表 key 下标为 index 的元素的值设置为 value
# 对空列表进行LSET
redis> EXISTS elist
(integer) 0
redis> LSET elist 0 xxm
(error) ERR no such key
# 对非空列表进行LSET
127.0.0.1:6379> lrange lxxm 0 -1
1) "java"
2) "maven"
3) "json"
4) "python"
5) "redis"
6) "mybatis"
127.0.0.1:6379> lset lxxm 0 jdk1.8
OK
127.0.0.1:6379> lrange lxxm 0 -1
1) "jdk1.8"
2) "maven"
3) "json"
4) "python"
5) "redis"
6) "mybatis"
# index超出范围
127.0.0.1:6379> lset lxxm 200 jdk11
(error) ERR index out of range
2.9 LRANGE
LRANGE KEY_NAME START END
返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定
127.0.0.1:6379> lrange lxxm 0 -1
1) "jdk1.8"
2) "maven"
3) "json"
4) "python"
5) "redis"
6) "mybatis"
127.0.0.1:6379> lrange lxxm 0 0
1) "jdk1.8"
127.0.0.1:6379> lrange lxxm 0 1
1) "jdk1.8"
2) "maven"
127.0.0.1:6379> lrange lxxm -4 -2
1) "json"
2) "python"
3) "redis"
2.10 LTRIM
LTRIM KEY_NAME START STOP
对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
# start 和 stop 都在索引范围内
127.0.0.1:6379> lrange lxxm 0 -1
1) "jdk1.8"
2) "maven"
3) "json"
4) "python"
5) "redis"
6) "mybatis"
127.0.0.1:6379> ltrim lxxm 0 1
OK
127.0.0.1:6379> lrange lxxm 0 -1
1) "jdk1.8"
2) "maven"
# 索引的 stop 比最大下标大
127.0.0.1:6379> lrange lxxm 0 -1
1) "redis"
2) "sql"
3) "python"
4) "java"
5) "jdk1.8"
6) "maven"
127.0.0.1:6379> ltrim lxxm 4 200
OK
127.0.0.1:6379> lrange lxxm 0 -1
1) "jdk1.8"
2) "maven" #保留了列表中索引 4 至 索引 200 上的元素
# start 和 stop 都比最大下标大
127.0.0.1:6379> lrange lxxm 0 -1
1) "json"
2) "redis"
3) "sql"
4) "java"
5) "jdk1.8"
6) "maven"
127.0.0.1:6379> ltrim lxxm 15 56
OK
127.0.0.1:6379> lrange lxxm 0 -1
(empty list or set) # 列表被清空了
2.11 LINDEX
返回列表 key 中,下标为 index 的元素
127.0.0.1:6379> lrange lxxm 0 -1
1) "json"
2) "redis"
3) "sql"
4) "java"
127.0.0.1:6379> lindex lxxm 1
"redis"
127.0.0.1:6379> lindex lxxm -2
"sql"
127.0.0.1:6379> lindex lxxm 20
(nil)
2.12 BLPOP
非阻塞行为
当BLPOP被调用时,如果给定 key 内至少有一个非空列表,那么弹出遇到的第一个非空列表的头元素,并和被弹出元素所属的列表的名字一起,组成结果返回给调用者。
它是 LPOP key 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP 命令阻塞,直到等待超时或发现可弹出元素为止
#
127.0.0.1:6379> lpush lxxm1 one
(integer) 1
127.0.0.1:6379> lpush lxxm2 two
(integer) 1
127.0.0.1:6379> blpop empty lxxm1 lxxm2 0 #empty 列表为空,被跳过,紧接着 command 列表的第一个元素被弹出。
1) "lxxm1" # 弹出元素所属的列表
2) "one" # 弹出元素所属的值
阻塞行为
如果所有给定 key 都不存在或包含空列表,那么 BLPOP 命令将阻塞连接,直到等待超时,或有另一个客户端对给定 key 的任意一个执行 LPUSH key value [value …] 或 RPUSH key value [value …] 命令为止。
# 确保两个 key 都不存在
127.0.0.1:6379> exists txxm1
(integer) 0
127.0.0.1:6379> exists txxm2
(integer) 0
127.0.0.1:6379> blpop txxm1 txxm2 3000 # 因为key一开始不存在,所以操作会被阻塞,直到另一客户端对 job 或者 command 列表进行 PUSH 操作。
# 打开另一个客户端,对txxm1进行push
127.0.0.1:6379> lpush txxm1 hello
(integer) 1
# 此时,原来执行 blpop 的客户端执行完毕,输出如下:
1) "txxm1" # 被 push 的 key
2) "hello" # 弹出的值
(8.37s) # 等待的时间
# 等待超时的情况
127.0.0.1:6379> blpop txxm1 txxm2 10
(nil)
(10.00s)
相同 key 被多个客户端同时阻塞的情况
相同的key被多个客户端同时阻塞 相同的 key 可以被多个客户端同时阻塞。不同的客户端被放进一个队列中,按『先阻塞先服务』(first-BLPOP,first-served)的顺序为 key 执行 BLPOP 命令。
事务中的 BLPOP
在MULTI/EXEC事务中的BLPOP 因此,一个被包裹在 MULTI / EXEC 块内的 BLPOP 命令,行为表现得就像 LPOP key 一样,对空列表返回 nil ,对非空列表弹出列表元素,不进行任何阻塞操作。
2.13 BRPOPLPUSH
BRPOPLPUSH LIST1 ANOTHER_LIST TIMEOUT
当列表 source 为空时, BRPOPLPUSH 命令将阻塞连接,直到等待超时,或有另一个客户端对 source 执行 LPUSH key value [value …] 或 RPUSH key value [value …] 命令为止。
# source 为非空列表
127.0.0.1:6379> lrange lxxm 0 -1
1) "json"
2) "redis"
3) "sql"
127.0.0.1:6379> lrange txxm1 0 -1
(empty list or set)
127.0.0.1:6379> lrange lxxm 0 -1
1) "json"
2) "redis"
127.0.0.1:6379> lrange txxm1 0 -1
1) "sql"
# source 为空列表
# 等待超时
127.0.0.1:6379> brpoplpush txxm3 msg 1
(nil)
(1.06s)
# 在timeout内,source被push
127.0.0.1:6379> brpoplpush txxm3 msg 300
# 另一个客户端进行lpush
127.0.0.1:6379> lpush txxm3 hello
(integer) 1
# 原客户端执行指令
"hello"
(75.62s)
#查看 msg
127.0.0.1:6379> lrange msg 0 -1
1) "txxm3"
2) "hello"
|