news 2026/6/10 8:11:25

Redis Stream 深入理解:它到底解决了什么问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis Stream 深入理解:它到底解决了什么问题

在 Redis 5.0 之前,如果你想用 Redis 做“消息”,基本绕不开 List 或 Pub/Sub。List 可以做阻塞消费,但消息一旦被取走就彻底消失,消费者挂了就是事故;Pub/Sub 更直接,消息不落地,订阅者一掉线,消息就像没发生过一样。这两种模型都不具备可靠消息系统的核心能力:可追溯、可确认、可重试。

Redis Stream 的出现,本质上就是 Redis 官方承认了一件事:Redis 需要一个真正的日志型消息结构

Stream 的核心设计非常像 Kafka:所有消息只追加、不修改,每条消息都有一个全局有序的 ID。这个 ID 由时间戳和序号组成,例如:

1700000000000-0 1700000000000-1

Redis 保证 ID 单调递增,这一点非常关键,因为它让 Stream 天然支持范围查询、顺序消费和断点恢复。

向 Stream 中写入消息使用的是XADD

XADD mystream * user alice action login

*表示让 Redis 自动生成 ID。每条消息不是一个简单字符串,而是一组 field-value,这一点和 List 最大的不同在于:Stream 的 value 是结构化的

真正让 Stream 成为“消息队列”的,并不是 XADD,而是消费组(Consumer Group)。消费组解决的是“同一条消息只能被一个消费者处理,并且必须被确认”。

你可以先创建一个消费组:

XGROUP CREATE mystream group1 0

0表示从头开始消费历史消息。

消费者使用XREADGROUP拉消息:

XREADGROUP GROUP group1 c1 COUNT 1 BLOCK 0 STREAMS mystream >

这里有一个非常容易被忽略但极其重要的点:
当这条消息被投递给消费者c1时,它并没有从 Stream 中删除,而是被放进了消费组的一个结构里,叫PEL(Pending Entries List)

PEL 的含义是:已投递,但尚未确认的消息

只要你没XACK,Redis 就认为这条消息“可能没处理完”。

XACK mystream group1 1700000000000-0

ACK 之后,这条消息才会从 PEL 中移除。但注意:消息本身依然留在 Stream 里,只是这个消费组不再关心它。

PEL 的存在,直接解决了 List 和 Pub/Sub 永远解决不了的问题:
消费者宕机怎么办?

假设消费者c1读到一条消息,还没来得及处理就挂了,这条消息就会一直躺在 PEL 里。你可以通过:

XPENDING mystream group1

看到有哪些“卡住”的消息,然后用:

XCLAIM mystream group1 c2 60000 1700000000000-0

把超过 60 秒没处理的消息,抢给另一个消费者c2
这一套机制,本质上就是 Redis 自己实现的at-least-once 消费模型

从内部实现来看,Stream 并不是一个简单的链表。Redis 使用的是Radix Tree(基数树)来存储消息 ID 和内容,这让它在 ID 有序的前提下,依然可以高效做区间扫描,比如:

XRANGE mystream 1700000000000-0 +

这也是为什么 Stream 可以非常自然地支持“重放历史消息”,而 List 和 Pub/Sub 做不到。

需要注意的是,Stream不会自动删除消息。如果你只消费、不裁剪,Stream 会无限增长:

XTRIM mystream MAXLEN ~ 100000

这里的~是近似裁剪,Redis 会在性能和精确度之间做权衡。

还有一个实践中的坑:PEL 一定要被清理。如果消费者逻辑有问题,消息一直不 ACK,PEL 会越来越大,最后看起来像“没消息可消费”,但实际上全卡在 PEL 里。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/4 21:43:37

数字化转型下零售门店管理软件的功能与选择考量

在实体零售朝着数字化转变这一潮流里,门店管理软件变成了商家为提高运营效率、优化顾客体验而使用的关键工具。这种软件一般整合了进销存管理、收银支付、会员营销、多渠道订单处理等各项功能,目的是协助商家达成业务流程的在线化以及数据化。当下市场上…

作者头像 李华
网站建设 2026/6/5 13:34:27

JBoltAI网关:Java企业级AI的稳定“交通枢纽”

在Java企业级AI应用开发里,AI请求的高效处理与稳定传输至关重要。JBoltAI框架的AI路由网关,凭借统一接入、智能路由、负载均衡和熔断降级等功能,为Java开发搭建起可靠的“交通枢纽”。统一接入:简化流程,提升效率在企业…

作者头像 李华
网站建设 2026/5/30 16:30:15

Xcode中iOS资源混淆问题与解决方案详解

iOS 资源混淆 概述 XCode项目中的文件夹分成两类: group 和 directory reference, 分别是虚结构和实结构. 黄色的 group 是默认的格式, 它的结构和磁盘上的文件夹毫无关系, 仅仅表示资源的逻辑组织结构, 这在管理源文件是非常方便. 同一段代码可以被很多项目使用, 也可能只使…

作者头像 李华
网站建设 2026/5/26 15:38:25

Git代码规范

分支命名分支与环境对应关系( 1 ) type(必须) : commit 的类别,只允许使用下面几个标识:常用的提交类型包括提交类型描述示例feat新功能增加(feature)feat: add user login featurefix修复BUGfix: correct …

作者头像 李华
网站建设 2026/6/6 22:06:59

嵌入式 C++ 高性能流式架构的设计

嵌入式 C 高性能流式架构的设计 摘要:在算力受限的嵌入式 SoC 平台上,高带宽传感器数据的实时处理是一个挑战。传统的基于多线程与操作系统原语的架构,往往受限于调度抖动、内存拷贝开销及锁竞争。 本文提出了一种平台无关的**“流式架构&am…

作者头像 李华