🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇
⭐ List 类型 ⭐
🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇
引言
继上篇文章的 hash 类型,这里介绍 Redis 中的列表的基本命令和使用以及实际应用。列表(List)是 Redis 提供的一种常用的数据结构,非常适合用来处理一系列有序的数据。
1. 什么是 Redis 列表?
Redis 列表是一种可以存储多个有序字符串的数据类型。你可以把它想象成一个简单的清单,比如购物清单或者待办事项列表。在这个列表里,每个条目都是一个字符串,并且它们按照添加的顺序排列。你可以在列表的两端进行插入或移除操作,也可以从列表中获取指定位置的数据。
特点:
- 有序性:列表中的元素是按照添加顺序排列的。
- 访问方式:可以通过数字索引来访问列表中的元素,索引可以从左到右(0, 1, 2...)或者从右到左(-1, -2, -3...)。
- 允许重复:列表中的元素可以重复出现。
2. 如何操作 Redis 列表?
添加元素
-
LPUSH命令:在列表的左侧(头部)添加一个或多个元素。例如:redis> LPUSH mylist "apple" (integer) 1 redis> LPUSH mylist "banana" "cherry" (integer) 3这个命令将
"banana"和"cherry"依次添加到mylist的最左边,结果是["cherry", "banana", "apple"]。 -
RPUSH命令:在列表的右侧(尾部)添加一个或多个元素。例如:redis> RPUSH mylist "date" (integer) 4 redis> RPUSH mylist "elderberry" "fig" (integer) 6这个命令将
"date"、"elderberry"和"fig"依次添加到mylist的最右边,结果是["cherry", "banana", "apple", "date", "elderberry", "fig"]。 -
LPUSHX和RPUSHX命令 :这些命令类似于LPUSH和RPUSH,但只有当键已经存在时才会执行插入操作。例如:redis> LPUSHX myotherlist "grape" (integer) 0 redis> RPUSHX mylist "grape" (integer) 7如果
myotherlist不存在,则不会添加任何元素;而mylist已经存在,所以会在其左侧添加"grape",结果是["grape", "cherry", "banana", "apple", "date", "elderberry", "fig"]。
获取元素
-
LRANGE命令:获取列表中特定范围内的所有元素。例如:redis> LRANGE mylist 0 2 1) "grape" 2) "cherry" 3) "banana" redis> LRANGE mylist -3 -1 1) "date" 2) "elderberry" 3) "fig"第一个命令返回了从第 1 个到第 3 个的所有元素,第二个命令返回了最后三个元素。
-
LINDEX命令:获取列表中某个特定位置的元素。例如:redis> LINDEX mylist 2 "banana" redis> LINDEX mylist -1 "fig"第一个命令返回了位于第 3 位的元素
"banana",第二个命令返回了最后一个元素"fig"。
删除元素

-
LPOP命令:从列表的左侧移除并返回第一个元素。例如:redis> LPOP mylist "grape"移除了
"grape",新的列表为["cherry", "banana", "apple", "date", "elderberry", "fig"]。 -
RPOP命令:从列表的右侧移除并返回最后一个元素。例如:redis> RPOP mylist "fig"移除了
"fig",新的列表为["cherry", "banana", "apple", "date", "elderberry"]。 -
LREM命令:删除列表中与给定值相匹配的元素。例如:redis> LREM mylist 1 "apple" (integer) 1 redis> LREM mylist 0 "banana" (integer) 1第一个命令移除了第一个出现的
"apple",第二个命令移除了所有"banana"元素,新的列表为["cherry", "date", "elderberry"]。
插入元素
-
LINSERT命令 :在特定位置插入元素。例如:redis> LINSERT mylist BEFORE "date" "avocado" (integer) 4 redis> LINSERT mylist AFTER "cherry" "blueberry" (integer) 5第一个命令在
"date"之前插入了"avocado",第二个命令在"cherry"之后插入了"blueberry",新的列表为["cherry", "blueberry", "avocado", "date", "elderberry"]。
查询长度
-
LLEN命令 :获取列表的长度。例如:redis> LLEN mylist (integer) 5
阻塞式操作
BLPOP 和 BRPOP 命令 :这些命令是 LPOP 和 RPOP 的阻塞版本。当列表为空时,这些命令不会立即返回空结果,而是等待一段时间,直到有新的元素被添加到列表中。例如:
redis> BLPOP mylist 0
1) "cherry"
2) "blueberry"
redis> BRPOP mylist 0
1) "mylist"
2) "elderberry"
如果 mylist 为空,BLPOP 和 BRPOP 会一直等待,直到有新元素被添加。


3. 实际应用场景
消息队列
在需要实现生产者-消费者模型的应用场景中,可以利用
LPUSH和BRPOP来创建一个消息队列。生产者将消息推入队列的一端,而消费者则从另一端取出消息处理。这种方式能够保证消息的有序性和并发消费的能力。
示例:
-
生产者:
redis> LPUSH queue "message1" (integer) 1 redis> LPUSH queue "message2" (integer) 2 -
消费者:
redis> BRPOP queue 0 1) "queue" 2) "message2" redis> BRPOP queue 0 1) "queue" 2) "message1"
社交媒体时间线
对于社交媒体平台来说,用户的动态更新通常按照时间顺序展示。通过使用 Redis 列表,我们可以轻松地维护每个用户的时间线。每当用户发布新内容时,就将其添加到列表顶部;而当用户浏览时,则按需加载最新的几条动态。
示例:
-
发布新微博:
redis> LPUSH user:1:timeline "tweet1" (integer) 1 redis> LPUSH user:1:timeline "tweet2" (integer) 2 -
查看最新 10 条微博:
redis> LRANGE user:1:timeline 0 9 1) "tweet2" 2) "tweet1"
任务调度
在某些后台系统中,可能需要定期执行一些任务。这时就可以把即将要执行的任务放进一个列表里,然后设置定时器逐个取出并执行这些任务。
示例:
-
添加任务:
redis> RPUSH tasks "task1" (integer) 1 redis> RPUSH tasks "task2" (integer) 2 -
执行任务:
redis> LPOP tasks "task1" redis> LPOP tasks "task2"
4. 内部机制简介
为了提高效率,Redis 会根据列表的实际大小选择不同的内部表示方法:
- 压缩列表(ziplist):如果列表中的元素不多且每个元素都很小,那么 Redis 会选择一种叫做压缩列表的方式来存储,这样可以节省内存空间。
- 链表(linkedlist):当列表变得很大或者包含大量大尺寸的元素时,Redis 会转而使用链表来表示这个列表,从而保持操作性能不受影响。
示例:
-
使用压缩列表:
redis> RPUSH smalllist "a" "b" "c" (integer) 3 redis> OBJECT ENCODING smalllist "ziplist" -
使用链表:
redis> RPUSH biglist "a" "b" "c" ... (超过 512 个元素) (integer) 513 redis> OBJECT ENCODING biglist "linkedlist"
5. 命令小结
| 操作类型 | 命令 | 时间复杂度 |
|---|---|---|
| 添加 | RPUSH key value [value ...] |
O(k),k 是元素个数 |
LPUSH key value [value ...] |
O(k),k 是元素个数 | |
| `LINSERT key BEFORE | AFTER pivot value` | |
| 查找 | LRANGE key start end |
O(s+n),s 是 start 偏移量,n 是 start 到 end 的范围 |
LINDEX key index |
O(n),n 是索引的偏移量 | |
LLEN key |
O(1) | |
| 删除 | LPOP key |
O(1) |
RPOP key |
O(1) | |
LREM key count value |
O(k),k 是元素个数 | |
LTRIM key start end |
O(k),k 是元素个数 | |
| 修改 | LSET key index value |
O(n),n 是索引的偏移量 |
| 阻塞操作 | BLPOP key [key ...] timeout |
O(1) |
BRPOP key [key ...] timeout |
O(1) |
以上就是有关 Redis 的列表的知识,后续会继续更新,感谢阅览!!
