文章目录
- LLEN
- LREM
- LTRIM
- LSET
- 阻塞版本命令
- BLPOP 和 BRPOP
- 区别
- 使用方式
- 命令小结
- 内部编码
LLEN
获取 list
的长度
语法:
LLEN key
- 时间复杂度: O ( 1 ) O(1) O(1)
- 返回值:
list
长度
LREM
删除 count
个 key
中的元素
语法:
LREM key count element
- 时间复杂度:
O
(
N
+
M
)
O(N+M)
O(N+M),
N
N
N 是
list
长度, M M M 是需要移除的元素个数 count > 0
:要删除的元素从左往右找count < 0
:要删除的元素从右往左找count = 0
:删除所有的指定元素
LTRIM
保留 start
和 stop
之间区间内的元素,区间外元素就直接被删除了
语法:
LTRIM key start stop
- 时间复杂度:
O
(
N
)
O(N)
O(N),
N
N
N 是被删除的元素个数
LSET
根据下标,修改元素
语法:
LSET key index element
- 时间复杂度:
O
(
N
)
O(N)
O(N)
LINDEX
可以很好的处理下标越界的情况,直接返回nil
。list
则会报错
阻塞版本命令
阻塞:当前的线程不走了,代码不继续执行了。会在满足一定的条件之后被唤醒
BLPOP 和 BRPOP
B
==> block
(阻塞),阻塞队列(BlockingQueue
)
使用队列来作为中间的“交易场所”,期望这个队列有两个特性:
- 线程安全
- 阻塞
- 如果队列为空,尝试出队列,就会产生阻塞。直到队列不空,阻塞解除
- 如果队列为满,尝试入队列,也会产生阻塞。直到队列不满,阻塞解除
Redis
中的 list
也相当于阻塞队列一样,线程安全是通过单线程模型支持的。阻塞,则只支持“队列为空”的情况,不考虑“队列满”
- 如果
list
中存在元素,那么BLPOP/BRPOP
和LPOP/RPOP
作用完全相同。 - 如果
list
中为空,那么BLPOP/BRPOP
就会产生阻塞,一直阻塞到队列不空为止
区别
阻塞版本会根据 timeout
,阻塞一段时间,期间 Redis
可执行其他命令
- 使用
BLPOP/BRPOP
的时候,这里是可以显示设置阻塞时间的(不一定是无休止的等待)
命令中如果设置了多个键,那么会从左向右进行遍历键,一旦有一个键对应的列表中可以弹出元素,命令立即返回
- BLPOP/BRPOP 都是可以同时去尝试获取多个
key
的列表的元素的 - 多个
key
对应多个list
,这多个list
哪个有元素了,就会返回哪个元素
如果多个客户端同时针对同一个 key
执行 POP
,则最先执行命令的客户端会得到弹出的元素
使用方式
语法:
BLPOP key [key ...] timeout
- 此处可以指定一个
key
或者多个key
,每个key
都对应一个list
- 如果这些
list
有任何一个非空,BLPOP 都能够把这里的元素给获取到,立即返回 - 如果这些
list
都为空,此时就要阻塞等待,等待其他客户端往这些list
中插入元素 - 此处还可以指定超时时间,单位是秒(
Redis 6
,超时时间允许设为小数;Redis 5
中,超时时间得是整数)
- 如果这些
- 针对一个非空的列表进行操作
- 返回的结果相当于一个
pair
(二元组) - 一方面是告诉我们当前的数据来自于哪个
key
- 一方面告诉我们取到的数据是啥
- 返回的结果相当于一个
- 针对空的列表进行操作
- 先
key
中没有元素的时候,一直阻塞。后来新开一个终端窗口,将key
里面新加元素,阻塞就结束了,并显示了阻塞时间
- 针对多个
key
- 当四个
key
都是空的时候,就会阻塞住,但只要其中一个key
有了元素,阻塞就会停止
当前这俩命令虽然可以一定程度的满足“消息队列”这样的需求,但整体来说,这俩功能还是比较有限
命令小结
内部编码
ziplist
(压缩列表),把数据按照更紧凑的压缩形式进行表示,节省空间。当元素个数多了,操作起来效率会降低- 当元素个数多了之后,就会变成
linkedlist
(链表)
quicklist
相当于是链表和压缩列表的结合,整体还是一个链表,链表的每个节点,是一个压缩列表
- 每个压缩列表,都不让它太大,同时再把多个压缩列表通过链式结构连起来