8.1.5 List类型与常用命令
List 是基于双向链表实现的有序集合,支持从两端高效插入与弹出,适合消息队列、时间线、任务列表、日志缓冲等场景。元素可重复,按插入顺序排列,支持按索引访问与范围查询。
原理草图(双向链表与队列消费)
核心命令与解释#
LPUSH key value [value ...]:从左侧插入一个或多个元素。RPUSH key value [value ...]:从右侧插入一个或多个元素。LPOP key [count]:从左侧弹出一个或多个元素。RPOP key [count]:从右侧弹出一个或多个元素。LRANGE key start stop:按索引范围获取元素(含 start/stop)。LLEN key:获取列表长度。LINDEX key index:获取指定索引元素(负数表示倒数)。LSET key index value:设置指定索引元素值。LINSERT key BEFORE|AFTER pivot value:在某元素前/后插入新元素。LTRIM key start stop:裁剪列表,只保留指定范围。BLPOP/BRPOP:阻塞弹出,常用于消费队列。RPOPLPUSH/BRPOPLPUSH:原子移动元素,实现可靠队列。
安装与连接示例#
若已安装 Redis 可跳过。以下以 Ubuntu 为例,演示本节可直接执行。
# 安装
sudo apt-get update
sudo apt-get install -y redis-server
# 启动
sudo systemctl enable --now redis-server
# 连接
redis-cli -h 127.0.0.1 -p 6379
完整示例:列表基本操作#
# 进入 redis-cli 后执行
FLUSHDB
RPUSH tasks task1 task2 task3 # 从右侧插入
LPUSH tasks task0 # 从左侧插入
LRANGE tasks 0 -1 # 查看全部
LLEN tasks # 长度
LINDEX tasks 2 # 获取索引 2
LSET tasks 2 task2-updated # 更新索引 2
LINSERT tasks AFTER task1 task1.5 # 插入
LTRIM tasks 0 3 # 只保留前 4 个
LRANGE tasks 0 -1
# 预期输出示例
# 1) "task0" "task1" "task1.5" "task2-updated"
队列与阻塞消费示例#
# 终端A:生产者
redis-cli RPUSH queue msg1 msg2 msg3
# 终端B:消费者(阻塞)
redis-cli BLPOP queue 10
# 10 秒超时返回 (nil),避免永远阻塞
可靠队列示例(处理队列)#
# 终端A:生产
redis-cli RPUSH queue job1 job2
# 终端B:消费并转移到 processing
redis-cli BRPOPLPUSH queue processing 5
# 处理完成后确认删除
redis-cli LREM processing 1 job1
性能与注意事项#
- 头尾插入/弹出为 O(1),
LRANGE、LINDEX为 O(n)。 LTRIM控制长度:日志缓冲常用LPUSH + LTRIM key 0 999。- 超长列表频繁随机访问建议拆分或使用 ZSet。
- 列表为空时
LPOP/RPOP返回nil,阻塞命令需设置超时。
常见排错#
- 阻塞命令一直卡住:
- 检查是否有生产者写入;确认超时参数是否为0(永不超时)。 - 索引越界:
-LSET时报错index out of range,先用LLEN检查长度。 - 数据被裁剪:
- 排查是否有LTRIM或定时裁剪逻辑。
练习#
- 使用
RPUSH创建一个包含 5 个元素的任务列表,并用LRANGE输出。 - 实现“循环队列”:使用
RPOPLPUSH queue queue让元素循环移动。 - 通过
BRPOPLPUSH queue processing实现可靠队列,处理完成用LREM删除。 - 使用
LTRIM将列表长度固定为 3,验证最旧元素被移除。