Redis Stream 做异步任务:先想清消费组和重试语义

Redis Stream 做异步任务:先想清消费组和重试语义

Redis Stream 可以用来做轻量异步任务队列,适合独立服务或中等规模后台任务。但它不是把消息 XADD 进去就完事。消费组、Pending 列表、ACK、重试、死信都要设计清楚,否则任务失败后会悄悄堆积。

异步任务系统的核心不是投递,而是失败后还能被正确处理。

一、基本消费链路

flowchart TD
  A[XADD Task] --> B[Stream]
  B --> C[Consumer Group]
  C --> D[Worker]
  D --> E[XACK]
  D --> F[Pending]

Worker 成功后 ACK,失败则留在 Pending。Pending 不处理,任务就会卡在那里。

二、创建 Stream 和消费组

XGROUP CREATE ai_jobs workers $ MKSTREAM
XADD ai_jobs * job_id 123 type summary

消费时使用 XREADGROUP。每个 worker 属于同一个 group,共同分担任务。

三、Pending 要定期扫描

XPENDING ai_jobs workers

如果某个 worker 挂了,它拿到但没 ACK 的消息会留在 Pending。需要用 XAUTOCLAIM 把超时消息转移给健康 worker。

XAUTOCLAIM ai_jobs workers worker-2 60000 0-0 COUNT 10

这一步不做,Redis Stream 就不是可靠队列,只是看起来像队列。

四、重试和死信要有上限

同一个任务失败太多次,就应该进入死信,而不是无限重试。

retry_policy:
  max_attempts: 3
  backoff: exponential
  dead_letter_stream: ai_jobs_dlq

死信不是垃圾桶,而是人工排查入口。要记录失败原因和最后一次错误。

还要考虑消息幂等。Redis Stream 可能因为重试或认领让同一任务被执行多次。任务处理逻辑必须能识别重复。

CREATE TABLE job_result (
  job_id VARCHAR(64) PRIMARY KEY,
  status VARCHAR(32),
  result_uri TEXT
);

写结果时用 job_id 做唯一键,已经完成的任务直接返回。这样重试不会生成两份结果。

五、总结

Redis Stream 可以做轻量异步任务队列,但要设计消费组、ACK、Pending 扫描、超时认领、重试和死信。

先想清失败语义,再选队列。否则任务不是执行了,而是丢在 Pending 里没人管。

Redis Stream 适合轻量任务,但如果需要复杂调度、延迟任务和更强事务语义,就要评估专门队列。工具要匹配问题,不要为了省组件把边界做模糊。

还要监控 Stream 长度、Pending 数和最老消息时间。队列系统最怕“还有消费”但其实已经落后很多。

stream_metrics:
  stream_length
  pending_count
  oldest_pending_age
  dead_letter_count

这些指标要有告警。否则任务堆积到用户投诉时,后台早就欠了一堆债。

如果任务有优先级,也不要把高低优先级混在同一个 Stream 里硬排队。可以拆 Stream,或者在消费者侧先处理高优先级任务。优先级策略越晚补,越容易影响已有消息语义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值