用 DUMP 解出 Stream 的底层结构验证:radix 树的每个 key 是节点首条消息的 ID(16 字节大端),value 是一个 listpack;默认每节点 100 条(或 4096 字节),10 万条消息 = 1000 个 key、平均 18.5 字节/条;按 ID 点查从 1000 条到 100 万条都是 4.3–4.5 µs。
在本机 Redis 上验证 Stream Entry ID 的规则:<毫秒>-<序号>,同一毫秒最多连续生成到 1140 号(5000 条管道写入落在 6 个毫秒里);显式 ID 必须严格递增;把最后一个 ID 造成未来后 * 仍沿着它递增;ID 是 64+64 位,用尽后再写会报错;XDEL 不会让 ID 回退。
在本机 Redis 上验证 Stream Consumer Group:创建起点 $ 与 0 的区别,同组内 3 个消费者读同一条流时消息互不重复(各拿 4 条),不同组各自独立读全部消息,XINFO GROUPS 里的 pending / lag / last-delivered-id 各是什么意思,以及 MKSTREAM、BUSYGROUP、CREATECONSUMER、DESTROY 的行为。
在本机 Redis 上验证 Stream 的 Pending Entries List:消息投递就进 PEL(记录消费者、idle、投递次数),XPENDING 汇总与明细的格式,重读历史会让投递次数 +1,NOACK 不进 PEL,PEL 只存 ID 不存内容(XDEL 后仍在),10 万条不 ack 会让内存增加约 94 字节/条。
在本机 Redis 上验证 XACK:它只把 ID 从组的 PEL 里移除,返回真实移除的条数(重复 ack、不存在的 ID 都返回 0),不会删除流里的消息(XLEN 不变);PEL 按组维护;并实测 Redis 8.x 新增的 XACKDEL 的 ACKED / KEEPREF / DELREF 三种策略对别的组 PEL 的影响。
用独立进程真实 kill -9 一个 Stream 消费者:连接断开后它的 PEL 仍留在组里、idle 持续增长、消息不会自动转给别的消费者;另一个消费者要用 XCLAIM 主动认领(投递次数 +1,min-idle 防重复认领);XGROUP DELCONSUMER 会直接丢弃 PEL,是个危险操作。
在本机 Redis 上验证 XAUTOCLAIM:用游标翻页认领超时未 ack 的消息(10 条 pending、COUNT 3 共 4 次调用,游标回到 0-0 表示结束),认领后 idle 归零且投递次数 +1,JUSTID 不增加投递次数,PEL 中已被 XDEL 的消息会被清掉并在返回值第三项列出。
10 万条消息的 Stream 内存回收实测:XACK 全部确认后内存回到 11.20 MB(只回收 PEL,XLEN 不变);XDEL 隔一条删一条内存不变(11.20 MB),连续删前一半才降到 5.60 MB;XTRIM MINID 效果与连续删除相同,XTRIM MAXLEN 0 清空后内存只剩 260 字节。
实测 Stream 的 MAXLEN ~(近似裁剪):逐条 XADD 时精确裁剪 XLEN 恒为 1000,近似裁剪在 1000–1099 之间锯齿(一次掉一个 100 条的节点);稳态下每条 XADD 耗时:不裁剪 1.90 µs、近似 2.76 µs、精确 5.44 µs;整节点裁剪很便宜(100 万条 0.0 ms),但 ~ 的默认 LIMIT 只删 1 万条。
用同一台本机 Redis 对比 Stream 与 List 做消息队列:10 万条 64 字节消息 List 73.5 B/条、Stream 81.7 B/条;管道入队 LPUSH 768k/s、XADD 510k/s;阻塞等待延迟量级相同(p50 约 0.2 ms);消费者崩溃时 List 的 5 条取出消息无处可查,Stream 在 PEL 里可认领;Stream 支持多消费组扇出与回看。
在本机 Redis 上复现 Pub/Sub 丢消息的三种情形:没有订阅者时消息直接消失;订阅者掉线 0.5 秒,300 条里丢了连续的 35 条(101–135);订阅者读得慢超过 client-output-buffer-limit pubsub 会被服务器断开(发到第 746 条时);服务器重启后订阅关系不保留。
把 Pub/Sub 与 Stream 放在同一实例上对比:消费者离线期间的 100 条,Pub/Sub 上线后一条也收不到、Stream 消费组一次读回 100 条;发布 10 万条 Pub/Sub 几乎不占内存、Stream 占 11.4 MB;PUBLISH 耗时随订阅者数线性增长(N=5000 时 17.7 ms),XADD 不受消费者数量影响。