REDIS · 故障语义实验

消息被“取走”以后,真的安全了吗?

案例:订单 #A881
支付后通知 + 审计

同一次宕机,三种模型留下三种现场

支付服务发出 order.paid。通知消费者刚拿到消息、还没写完审计记录就崩溃。逐步推进时间线,观察 Redis 里究竟还剩什么,以及恢复后的消费者能不能把工作接回来。

List:队列里没有“处理中”这个状态

BRPOP 把元素交给消费者时,也从 List 删除它。若业务处理尚未提交就宕机,Redis 不知道还有一项工作没有完成。

故障语义:至多一次
  1. 1生产事件

    支付服务发布 order.paid

  2. 2领取 / 在线接收

    消费者开始写通知与审计

  3. 3消费者宕机

    业务尚未提交,连接断开

  4. 4恢复处理

    新实例尝试找回未完工作

此刻的系统状态

消费者:在线
支付服务 等待生产
Redis List notify:orders
审计消费者 等待消息
队列内容0 项
空
消费者手中0 项
空
切换模型会从同一故障的起点重新开始
当前判断:消息尚未发出

先生产订单事件,再观察模型是否会为“已经交付、尚未完成”的任务保留证据。

选型不看“像不像队列”,要看故障后能否交代

模型Redis 是否保存消息领取后是否有待确认记录离线期间更适合
List + BRPOP领取前保存没有队列可积压;已取出的任务可能丢可容忍少量丢失的简单任务
Pub/Sub不保存没有消息直接错过在线广播、瞬时状态刷新
Stream + Group按保留策略保存PEL 记录归属与空闲时间恢复后可读积压或认领超时消息需要可追踪、可恢复的异步任务

别把 Stream 叫作“迷你 Kafka”。它能解决消费组、重放和未确认追踪,但分区吞吐、长期日志存储、跨集群复制与生态能力仍是另一套工程问题。订单审计能不能留在 Redis Stream,要由数据保留、容量、恢复时间和不可丢失级别共同决定。