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或者在消费者侧先处理高优先级任务。优先级策略越晚补越容易影响已有消息语义。
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或者在消费者侧先处理高优先级任务。优先级策略越晚补越容易影响已有消息语义。