Redis 列表与简单队列

发布日期:2026-07-24 10:01:46  浏览量 :0
发布日期:2026-07-24 10:01:46  
0

Redis 列表是一个有序的字符串序列,你可以从两端进行推入和弹出操作。这种简单的结构使其天然适合两种常见需求:一种是生产者添加任务、消费者获取任务的队列;另一种是仅保留最近项目的有限动态源。列表并非能解决所有队列问题(流类型更适合处理高要求场景),但对于简单的先进先出任务和“最新 N 项”动态源而言,它们是快速且正确的工具。

这是《Redis 大师课》的第五部分,继哈希之后。

推入与弹出

列表支持左右两端的操作:

LPUSH queue:emails "job1"    # 添加到头部(左侧)
RPUSH queue:emails "job2"    # 添加到尾部(右侧)
LPOP queue:emails            # 从头部移除并返回元素
RPOP queue:emails            # 从尾部移除并返回元素
LLEN queue:emails            # 获取长度
LRANGE queue:emails 0 -1     # 获取所有元素

将一端的推入操作与另一端的弹出操作结合,你就得到了一个队列。LPUSH 加上 RPOP 构成先进先出模式:最旧的项目会被取出。LPUSH 加上 LPOP 构成后进先出模式,即栈。这些操作都是原子的,因此多个生产者和消费者可以安全地访问同一个列表。

简单的工作队列

基本的工作队列由生产者执行 LPUSH 推送任务,工作者执行 RPOP 获取任务:

# 生产者
LPUSH jobs:email '{"to":"a@b.com","template":"welcome"}'

# 工作者
RPOP jobs:email    # 获取下一个任务,如果队列为空则返回 nil

普通 RPOP 的问题在于,当队列为空时会立即返回 nil,因此工作者必须在循环中轮询,这会消耗中央处理器资源并增加延迟。解决方案是使用阻塞变体:

BRPOP jobs:email 5    # 等待最多 5 秒以获取任务,然后返回

BRPOP 会阻塞直到有可用项目(或超时结束),因此工作者可以高效休眠,并在任务到达的瞬间唤醒。这将列表变成了一个无需轮询的真正基于推送的工作队列。

可靠性缺口

在使用列表作为工作队列之前,需要了解一个实际的局限性。使用 RPOPBRPOP 时,一旦工作者弹出一个任务,该任务就会从列表中消失。如果工作者在处理过程中崩溃,任务就会丢失,因为它既不在队列中,也未完成。普通列表提供的是“最多一次”交付保证,这对于允许丢弃的任务来说是可以接受的,但对于不能丢失的任务来说则是错误的选择。

经典的缓解措施是使用 LMOVE(或较旧的 RPOPLPUSH),它可以在一步中原子地从队列弹出并推送到“处理中”列表:

LMOVE jobs:email jobs:processing RIGHT LEFT

现在,当工作者处理任务时,该任务位于 jobs:processing 中。如果成功,工作者会将其从中移除;如果发生崩溃,它仍保留在处理列表中,可以被恢复

免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。

分享到:

长按或扫码识别 分享给好友

长按或扫码识别 分享给好友
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据