1802 字
约 6 分钟
9
创建列表并添加元素
列表类型概述
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。列表最多可存储 2^32 - 1 个元素。
列表结构示意图
←元素1元素2元素3元素4→
左端(头部) ← 列表 → 右端(尾部)
📝 基本操作命令
列表类型的基础插入和删除操作:
| 命令 | 描述 | 示例 |
|---|---|---|
| LPUSH key element [element ...] | 从左端(头部)插入元素 | LPUSH mylist "world" "hello" |
| RPUSH key element [element ...] | 从右端(尾部)插入元素 | RPUSH mylist "redis" |
| LPOP key | 从左端(头部)弹出元素 | LPOP mylist |
| RPOP key | 从右端(尾部)弹出元素 | RPOP mylist |
| LLEN key | 获取列表长度 | LLEN mylist |
| LINDEX key index | 获取指定索引的元素 | LINDEX mylist 0 |
| LSET key index element | 设置指定索引的元素值 | LSET mylist 0 "new_value" |
基本操作示例:
# 创建列表并添加元素
LPUSH tasks "task3" "task2" "task1" # 从左端插入
RPUSH tasks "task4" "task5" # 从右端插入
# 列表内容:["task1", "task2", "task3", "task4", "task5"]
# 获取列表信息
LLEN tasks # 返回: 5
LINDEX tasks 0 # 返回: "task1" (第一个元素)
LINDEX tasks -1 # 返回: "task5" (最后一个元素)
# 弹出元素
LPOP tasks # 返回: "task1"
RPOP tasks # 返回: "task5"
# 列表内容:["task2", "task3", "task4"]
# 修改元素
LSET tasks 0 "updated_task2" # 修改第一个元素
LINDEX tasks 0 # 返回: "updated_task2"
🔍 范围操作命令
获取和操作列表中的元素范围:
| 命令 | 描述 | 示例 |
|---|---|---|
| LRANGE key start stop | 获取指定范围的元素 | LRANGE mylist 0 2 |
| LTRIM key start stop | 保留指定范围的元素 | LTRIM mylist 0 99 |
| LINSERT key BEFORE | AFTER pivot element | 在指定元素前/后插入 |
| LREM key count element | 删除指定数量的元素 | LREM mylist 2 "hello" |
范围操作示例:
# 创建测试列表
RPUSH numbers 1 2 3 4 5 6 7 8 9 10
# 获取范围元素
LRANGE numbers 0 4 # 返回: ["1", "2", "3", "4", "5"]
LRANGE numbers -3 -1 # 返回: ["8", "9", "10"] (最后3个)
LRANGE numbers 0 -1 # 返回: 所有元素
# 保留指定范围
LTRIM numbers 0 4 # 只保留前5个元素
LRANGE numbers 0 -1 # 返回: ["1", "2", "3", "4", "5"]
# 插入元素
LINSERT numbers AFTER "3" "3.5" # 在"3"后插入"3.5"
LRANGE numbers 0 -1 # 返回: ["1", "2", "3", "3.5", "4", "5"]
# 删除元素
RPUSH duplicates "a" "b" "a" "c" "a"
LREM duplicates 2 "a" # 删除2个"a"
LRANGE duplicates 0 -1 # 返回: ["b", "c", "a"]
⏰ 阻塞操作命令
当列表为空时,阻塞等待新元素的命令:
| 命令 | 描述 | 示例 |
|---|---|---|
| BLPOP key [key ...] timeout | 阻塞式左端弹出 | BLPOP queue1 queue2 30 |
| BRPOP key [key ...] timeout | 阻塞式右端弹出 | BRPOP queue1 30 |
| BRPOPLPUSH source destination timeout | 阻塞式弹出并推入另一个列表 | BRPOPLPUSH queue1 queue2 30 |
阻塞操作示例:
# 消费者等待任务(阻塞30秒)
BLPOP task_queue 30
# 如果task_queue为空,将阻塞等待30秒
# 如果有新任务被推入,立即返回
# 生产者添加任务(在另一个连接中)
LPUSH task_queue "new_task"
# 此时阻塞的BLPOP会立即返回 ["task_queue", "new_task"]
# 多队列监听
BLPOP high_priority_queue normal_queue low_priority_queue 0
# 按优先级顺序检查队列,0表示永久阻塞
# 原子性转移
BRPOPLPUSH processing_queue completed_queue 30
# 从processing_queue右端弹出,推入completed_queue左端
🔄 列表间操作
在不同列表之间移动元素:
| 命令 | 描述 | 示例 |
|---|---|---|
| RPOPLPUSH source destination | 从源列表右端弹出,推入目标列表左端 | RPOPLPUSH list1 list2 |
列表间操作示例:
# 任务处理流程
RPUSH todo "task1" "task2" "task3"
RPUSH doing
RPUSH done
# 开始处理任务
RPOPLPUSH todo doing # 将任务从todo移到doing
LRANGE doing 0 -1 # 返回: ["task3"]
# 完成任务
RPOPLPUSH doing done # 将任务从doing移到done
LRANGE done 0 -1 # 返回: ["task3"]
# 查看各阶段任务
LRANGE todo 0 -1 # 返回: ["task1", "task2"]
LRANGE doing 0 -1 # 返回: []
LRANGE done 0 -1 # 返回: ["task3"]
实际应用场景
📨 消息队列
使用列表实现简单的消息队列系统:
# 生产者发送消息
LPUSH message_queue "{\"id\": 1, \"type\": \"email\", \"to\": \"[email protected]\"}"
LPUSH message_queue "{\"id\": 2, \"type\": \"sms\", \"to\": \"13800138000\"}"
# 消费者处理消息
BRPOP message_queue 30 # 阻塞等待消息
# 可靠队列(处理中队列)
BRPOPLPUSH message_queue processing_queue 30
# 处理完成后
LREM processing_queue 1 "processed_message"
# 失败重试
RPOPLPUSH processing_queue retry_queue
📰 最新动态
存储用户的最新动态或文章列表:
# 发布新动态
LPUSH user:1001:timeline "{\"id\": 101, \"content\": \"今天天气不错\", \"time\": 1609459200}"
LPUSH user:1001:timeline "{\"id\": 102, \"content\": \"学习Redis\", \"time\": 1609462800}"
# 获取最新10条动态
LRANGE user:1001:timeline 0 9
# 限制动态数量(只保留最新100条)
LTRIM user:1001:timeline 0 99
# 获取特定动态
LINDEX user:1001:timeline 0 # 最新动态
LINDEX user:1001:timeline -1 # 最早动态
📊 排行榜
实现简单的排行榜功能:
# 添加分数记录
LPUSH game:leaderboard "player1:1000"
LPUSH game:leaderboard "player2:1200"
LPUSH game:leaderboard "player3:800"
# 获取排行榜
LRANGE game:leaderboard 0 9 # 前10名
# 更新分数(需要先删除旧记录)
LREM game:leaderboard 1 "player1:1000"
LPUSH game:leaderboard "player1:1500"
# 注意:对于复杂排行榜,建议使用Sorted Set
🔄 任务调度
实现任务调度和处理流程:
# 任务提交
LPUSH task:pending "{\"id\": 1, \"type\": \"image_process\", \"file\": \"image1.jpg\"}"
LPUSH task:pending "{\"id\": 2, \"type\": \"video_encode\", \"file\": \"video1.mp4\"}"
# 工作进程获取任务
BRPOPLPUSH task:pending task:processing 30
# 任务完成
RPOPLPUSH task:processing task:completed
# 任务失败
RPOPLPUSH task:processing task:failed
# 重试失败任务
RPOPLPUSH task:failed task:pending
# 监控队列状态
LLEN task:pending # 待处理任务数
LLEN task:processing # 处理中任务数
LLEN task:completed # 已完成任务数
LLEN task:failed # 失败任务数
性能优化建议
- 避免大列表:单个列表元素数量不宜过多(建议小于10万)
- 使用阻塞操作:在队列场景中使用 BLPOP/BRPOP 避免轮询
- 批量操作:使用 LPUSH/RPUSH 的多元素版本减少网络往返
- 合理使用索引:避免频繁使用 LINDEX 访问中间元素
- 定期清理:使用 LTRIM 限制列表大小
- 选择合适的端:根据业务需求选择从左端还是右端操作
列表 vs 其他数据类型
数据类型选择建议:
- List vs Set:List允许重复元素且有序,Set不允许重复且无序
- List vs Sorted Set:List按插入顺序排序,Sorted Set按分数排序
- List vs Stream:Stream更适合复杂的消息队列场景
- 使用List的场景:消息队列、最新动态、简单排行榜、任务调度
评论
0 条
还没有评论,先写一条吧。