列表
Redis 的列表是一种线性的有序结构,可以按照元素被推入列表中的顺序来存储元素。这些元素既可以是文字数据,又可以是二进制数据,并且列表中的元素可以重复出现。
基本命令
LPUSH
将一个或多个元素依次推入列表左端,返回当前列表包含的元素数量。
当列表不存在,会创建一个新列表。
1 | -- 返回 1。hanzhang |
时间复杂度:O(n)
RPUSH
将一个或多个元素依次推入列表右端,返回当前列表包含的元素数量。
当列表不存在,会创建一个新列表。
1 | -- 返回 4.hanhan hanzuo hanzhang hanyang |
时间复杂度:O(n)
LPUSHX
当列表存在的情况下,将一个或多个元素依次推入列表左端,返回当前列表包含的元素数量。
当列表不存在的情况下,不会创建新列表,并返回 0.
时间复杂度:O(n)
RPUSHX
当列表存在的情况下,将一个或多个元素依次推入列表右端,返回当前列表包含的元素数量。
当列表不存在的情况下,不会创建新列表,并返回 0.
时间复杂度:O(n)
LPOP
移除左边第一个元素,并返回。
列表不存在,则返回 nil。
1 | -- hanhan |
时间复杂度:O(1)
RPOP
移除右边第一个元素,并返回。
列表不存在,则返回 nil。
1 | -- hanshen |
时间复杂度:O(1)
RPOPLPUSH
移除右边第一个元素,并从左边推入 target 列表。
源列表不存在,则返回 nil。
1 | -- 同源。hanyang hanzhang |
时间复杂度:O(1)
LLEN
获取列表长度。
不存在则返回 0。
1 | -- 返回 school 的长度 |
时间复杂度:O(1)
LINDEX
返回列表指定下标的元素。
- 正索引从左端 0 开始;
- 负索引从右端 -1 开始;
列表不存在或下标不合法则返回 nil.
1 | -- hanzhang hantang hanshen |
时间复杂度:O(n)
LRANGE
获取列表指定闭区间范围的所有元素。
- 起止索引都超过,返回 nil;
- 其中一个超过,则修正为实际范围(左端为 0,右端为 -1);
1 | -- 列表的所有元素 |
时间复杂度:O(n)
LSET
设置列表指定下标的元素。
下标不合法会抛出错误。
1 | -- 设置 ok |
时间复杂度:O(n)
LINSERT
将新元素插入到指定列表元素的前或后。
指定元素不存在,返回 -1。
只操作满足条件的第一个指定元素。
1 | -- 将 hanzhang 插入到 hanhan 前面 |
时间复杂度:O(n)
LTRIM
保留指定下标闭区间元素。
正负索引都可。
1 | -- 保留 0-3 闭区间元素 |
时间复杂度:O(n)
LREM
移除列表元素,返回移除的个数。
1 | RPUSH name "hanzhang" "hantang" "hanshen" "hanzhang" "hantang" "hanshen" |
时间复杂度:O(n)
BLPOP
带有阻塞的左端弹出操作,单位是 s。
timeout 为 0 时,表示一直等待,知道有消息。
1 | -- 左端弹出 school 元素,阻塞最多 10s |
同时很多线程阻塞时,先阻塞,先服务。
时间复杂度:O(n)
BRPOP
作用同 BLPOP,只是从右端弹出。
BRPOPLPUSH
作用同 RPOPLPUSH,只是带有阻塞功能。
时间复杂度:O(1)
示例
使用 BLPOP 实现异步处理消息
Producer 只需要将消息 PUSH 到 redis 中,然后处理自己的业务。而 redis 中监听该消息的程序 Consumer 会后续处理,实现了消息生产者与消费者的解耦。
1 | // Producer |
异步阻塞方式,使得 Consumer 程序更为简单,不需要 while true 进行处理,减少了 CPU 消耗;
总结
- 列表是线性有序结构,元素可重复;
- POP 和 PUSH 都可以进行双端操作,LINSERT 可以插入元素;
- LREM 可以删除元素,LTRIM 对列表进行截取;
- LRANGE 会对下标进行修正,左端为 0,右端为 -1;
- BLPOP、BRPOP 和 BRPOPLPUSH 当列表为空时,带有阻塞;