Redis 教程:数据类型 List 详解以及使用场景

· Redis笔记 Redis 缓存 数据结构 入门笔记 NoSQL · 0 阅读 · 约 4 分钟

前言

Redis 中的 List 是一个有序的字符串列表,按照插入顺序排序,可以在列表的头部(左侧)或尾部(右侧)插入元素。一个 List 最多可以存储 2^32 - 1 个元素(约 42 亿),非常适合用来实现队列、栈、最新消息列表等结构。

底层实现

在 Redis 3.2 之前,List 的底层编码是 ziplist(压缩列表)和 linkedlist(双向链表)二选一:

  • 元素数量少且单个元素较短时使用 ziplist,节省内存
  • 否则转换为 linkedlist

Redis 3.2 之后统一使用 quicklist(快速列表),它是一个由 ziplist 组成的双向链表,兼顾了内存效率和读写性能。可以通过 list-max-listpack-size 配置每个节点的长度。

常用命令

插入与弹出

# 从左侧插入
LPUSH key value1 value2

# 从右侧插入
RPUSH key value1 value2

# 从左侧弹出
LPOP key

# 从右侧弹出
RPOP key

# 阻塞式弹出,列表为空时等待指定秒数
BLPOP key 10
BRPOP key 10

查看与获取

# 查看指定范围的元素,0 -1 表示全部
LRANGE key 0 -1

# 获取列表长度
LLEN key

# 获取指定下标的元素
LINDEX key 0

其他操作

# 保留指定范围的元素,其余删除
LTRIM key 0 99

# 从列表 source 的右侧弹出一个元素,插入到列表 destination 的左侧
RPOPLPUSH source destination

# 阻塞版本的 RPOPLPUSH
BRPOPLPUSH source destination 10

# 在指定元素前后插入新元素
LINSERT key BEFORE pivot value
LINSERT key AFTER pivot value

# 删除指定数量的等于 value 的元素
LREM key count value

# 修改指定下标的元素
LSET key 0 newValue

使用场景

1. 消息队列

利用 LPUSH + BRPOP 的组合,可以实现一个简单的消息队列:生产者从左侧写入消息,消费者从右侧阻塞式读取。

# 生产者
LPUSH queue "task1"

# 消费者,列表为空时最多阻塞 30 秒
BRPOP queue 30

如果需要保证消息不丢,可以用 BRPOPLPUSH,消费者取出消息的同时备份到另一个列表,处理完成后再删除备份。

2. 最新消息列表

比如朋友圈动态、最新公告等,只需要展示最新的 N 条数据:

# 插入新动态
LPUSH user:1:timeline "post1001"

# 只保留最新 100 条
LTRIM user:1:timeline 0 99

# 读取最新 20 条
LRANGE user:1:timeline 0 19

3. 栈与队列

  • LPUSH + LPOP:先进后出,实现栈
  • LPUSH + RPOP:先进先出,实现队列
  • LPUSH + BRPOP:带阻塞能力的队列

4. 抽奖与轮询

用 LRANGE 随机范围配合业务逻辑可以做简单抽奖;用 RPOPLPUSH 可以实现任务轮询,把处理完的任务转回另一个列表形成循环。

注意事项

  1. List 的 LRANGE 在数据量大时是 O(N) 操作,避免在长列表上频繁大范围读取
  2. LSET 只能修改已存在的下标,越界会报错
  3. 消息队列场景下,Redis 没有原生 ACK 机制,可靠性要求高的业务建议使用专业的消息中间件
  4. 使用 BLPOP、BRPOP 这类阻塞命令时要注意连接超时和连接池配置

小结

List 是 Redis 中最常用的数据类型之一,底层 quicklist 兼顾性能与内存。掌握它之后,消息队列、最新列表、任务轮询等场景都能用非常简单的命令搞定。下一篇可以继续聊聊 Set 与 ZSet。