Redis 列表(List)

Redis 列表(List)完全攻略

“双向链表” —— 消息队列、最新列表、时间线、任务调度… 轻量级队列首选!


一、List 核心特点

特性说明
底层结构双向链表linkedlist)或 压缩列表ziplist
有序插入顺序保持不变
允许重复同一元素可多次出现
最大长度2^32 – 1(约 42 亿)
核心操作 O(1)LPUSH / RPUSH / LPOP / RPOP
阻塞操作BLPOP / BRPOP 支持阻塞等待
内部编码小列表 → ziplist,大列表 → linkedlist

二、List 命令全表(共 18 个)

命令说明示例
LPUSH key v1 v2左插入(头部)LPUSH tasks "backup"
RPUSH key v1右插入(尾部)RPUSH queue "msg"
LPOP key左弹出(头部)LPOP tasks
RPOP key右弹出(尾部)RPOP queue
BLPOP key timeout阻塞左弹出BLPOP tasks 30
BRPOP key timeout阻塞右弹出BRPOP queue 0
LRANGE key 0 -1查看全部LRANGE list 0 -1
LINDEX key 0获取索引LINDEX list 0
LLEN key长度LLEN queue
LREM key count value删除元素LREM list 2 "dup"
LSET key index value设置索引值LSET list 0 "new"
LINSERT key BEFORE|AFTER pivot v插入到指定元素前后LINSERT list BEFORE "b" "x"
LTRIM key start end保留区间LTRIM list 0 99
RPOPLPUSH src dest原子移动(右出左进)RPOPLPUSH q1 q2
BRPOPLPUSH src dest timeout阻塞版移动BRPOPLPUSH q1 q2 0

三、核心实战场景


1. 消息队列(生产者-消费者)

# 生产者
RPUSH msg:queue "task1" "task2" "task3"

# 消费者(阻塞等待)
BRPOP msg:queue 0
# 返回: 1) "msg:queue" 2) "task3"

轻量级队列首选,比 Stream 简单


2. 最新列表 / 时间线

# 发布动态
LPUSH timeline:user:1001 "post:3001" "post:3002"

# 获取最新10条
LRANGE timeline:user:1001 0 9

# 限制长度(只保留100条)
LTRIM timeline:user:1001 0 99

3. 任务调度(延迟队列)

# 延迟5秒执行
RPUSH delay:queue "task:123"
EXPIRE delay:queue 5

# 消费者轮询
BRPOP delay:queue 1

更推荐用 Sorted Set 做精确延迟队列


4. 环形缓冲区(日志/监控)

RPUSH logs "error: db down"
LTRIM logs 0 999   # 只保留最新1000条

5. 原子任务转移(可靠队列)

# 从待处理 → 处理中
RPOPLPUSH pending:jobs processing:jobs

# 处理完成 → 删除
LREM processing:jobs 1 "job:123"

四、List vs String/Hash 对比

场景推荐
顺序访问List
随机访问StringHash
频繁中间插入/删除不推荐(O(N))
需要去重Set
复杂消息 + 消费组Stream

五、内部编码优化(ziplist vs linkedlist)

# 小列表 → ziplist(省内存)
LPUSH small a b c
OBJECT ENCODING small   → "ziplist"

# 大列表 → linkedlist
LPUSH large {1..10000 elements}
OBJECT ENCODING large   → "linkedlist"

切换阈值(配置文件)

配置默认值说明
list-max-ziplist-size-2-2 = 最大 8KB
list-compress-depth00 = 不压缩

生产建议:保持默认,避免大 List


六、性能与内存优化建议

建议说明
避免大 List> 10,000 元素 → 拆分
控制长度LTRIM 限制
阻塞弹出BLPOP / BRPOP 更高效
Pipeline 批量插入减少网络 RTT
设置 TTL防止内存泄漏
# 批量插入 1000 条
redis-cli --pipe < commands.txt

七、大 List 排查与拆分

排查大 List

redis-cli --bigkeys
# Biggest list found "msg:queue" with 100000 items

拆分方案

# 原:LPUSH msg:queue "task1" "task2" ...
# 拆:按时间分片
LPUSH msg:queue:20251112 "task1"
LPUSH msg:queue:20251113 "task2"

八、一键速查表

# 队列
RPUSH q v
BRPOP q 0

# 最新列表
LPUSH feed v
LRANGE feed 0 9
LTRIM feed 0 99

# 管理
LLEN q
LINDEX q 0
LREM q 1 "dup"
LTRIM q 0 999

# 原子移动
RPOPLPUSH src dest

九、客户端代码示例

Python (redis-py)

import redis
r = redis.Redis()

# 生产者
r.rpush('tasks', 'backup', 'clean', 'report')

# 消费者(阻塞)
task = r.brpop('tasks', timeout=0)
print(task)  # (b'tasks', b'report')

# 最新动态
r.lpush('timeline:1001', 'post:1', 'post:2')
r.ltrim('timeline:1001', 0, 99)
posts = r.lrange('timeline:1001', 0, 9)

Go (go-redis)

ctx := context.Background()
rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})

rdb.RPush(ctx, "queue", "task1")
task, _ := rdb.BRPop(ctx, 0, "queue").Result()
fmt.Println(task) // [queue task1]

十、常见问题与解决方案

问题原因解决方案
内存暴涨List 无限增长LTRIM
LPOP 卡顿List 太大拆分或用 Stream
消息丢失进程崩溃RPOPLPUSH 可靠队列
重复消费无 ACK用 Stream

十一、List 在高并发中的妙用

1. 可靠队列模式(处理中队列)

# 消费者
task = RPOPLPUSH pending:jobs processing:jobs
# 处理 task
LREM processing:jobs 1 task   # 确认完成

2. 限流队列

LPUSH rate:limit:api:1001 "1"
LTRIM rate:limit:api:1001 0 59   # 保留60个
EXPIRE rate:limit:api:1001 60
LLEN rate:limit:api:1001 > 60 → 限流

完成!你已精通 Redis List!

# 一行命令体验 List 全功能
redis-cli <<EOF
RPUSH q a b c
LPUSH q x y
LRANGE q 0 -1
BRPOP q 1
LLEN q
LTRIM q 0 1
EOF

下一步推荐

  1. Redis Set 去重集合
  2. Redis Stream 高级队列
  3. List + Lua 实现复杂队列

需要我送你

  • “高可靠任务队列(pending + processing)”
  • “社交时间线完整方案(List + ZSet)”
  • “限流系统(List + Pipeline)”

回复:可靠队列 | 时间线 | 限流 即可!

文章已创建 2481

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部