讲师中心 微信公众号

工具推荐

视频效率加速
AniShort
AniShort

AI短剧协同制作平台

Laper
Laper

剧本策划到成片协作

立刻MV
立刻MV

低成本歌曲 MV、视频生成

updream

一键生成高质量推广成片

Python Redis ZSET 实现的延时队列

胖墨姑娘_8488

胖墨姑娘_8488

发布时间:2026-02-19 11:23:09

|

560人浏览过

|

来源于php中文网

原创

ZADD用时间戳作score易漏任务,因系统时钟回拨、服务时间不同步或客户端时间不准导致score小于当前时间;须统一用毫秒级整数、写入前校验score≥当前时间、由消费者本地生成时间戳。

python redis zset 实现的延时队列

为什么 zadd 时间戳当 score 容易漏任务

Redis ZSET 延时队列本质是靠 zadd 把任务塞进有序集合,score 用时间戳(秒级或毫秒级),再用 zrangebyscore 拉出已到时间的任务。但很多人直接用 time.time() 当 score,结果发现:刚加进去的任务立刻被消费了。

原因很简单:系统时钟可能回拨、不同服务时间不同步、或者你本地跑测试时手快多点了几次,导致写入的 score 小于当前服务器时间。ZSET 不校验逻辑合理性,只按数字大小排。

  • 务必用 int(time.time() * 1000) 统一毫秒级,避免浮点误差和精度丢失
  • 写入前检查 score >= current_ms,不满足就 warn 或 fallback 到 current_ms
  • 不要依赖客户端时间,所有时间戳由消费者所在服务生成(比如 Celery worker 本地取)

zpopbyscore 不存在?得用 zrangebyscore + zrem 组合

Redis 原生没有原子性地“取出并删除”指定 score 范围成员的命令。zpopbyscore 是 Redis 6.2+ 才加的,而且默认不带 WITHSCORES,老版本根本不能用。

生产环境大概率是 Redis 5.x 或 6.0,必须自己组合操作。但要注意并发:两个 worker 同时 zrangebyscore 拿到同一堆任务,都去 zrem,会重复执行。

立即学习“Python免费学习笔记(深入)”;

Python Hardener
Python Hardener

通过完整的安全审查、代码整洁重构、健壮的错误处理、正确的日志记录以及完整的文档字符串覆盖,强化 Python 脚本。

下载
  • 用 Lua 脚本封装 zrangebyscore + zrem,保证原子性(示例里 key 是 delay_queue,score 上界是 now_ms):
eval "local res = redis.call('zrangebyscore', KEYS[1], '-inf', ARGV[1], 'LIMIT', 0, 10); if #res > 0 then redis.call('zrem', KEYS[1], unpack(res)); end; return res" 1 delay_queue 1717023456000
  • 别用 ZRANGEBYSCORE ... WITHSCORES 然后手动解析数组——返回值是 [member1, score1, member2, score2],容易索引错位
  • 限制每次最多取 10~20 条,避免单次操作太久阻塞 Redis

任务失败后怎么重试?别直接 zadd 回原队列

延时队列不是“失败就重来”的地方。如果一个任务执行失败,直接 zadd delay_queue now_ms+60000 task_data,看起来是 1 分钟后重试,但实际会破坏 ZSET 的时间序:新 score 可能比队列里其他 pending 任务还小,导致它插队执行。

更糟的是,如果失败是永久性的(比如参数错误、下游不可用),这个任务会不断重试、卡住整个消费节奏。

  • 失败任务应转入独立的 retry_queue,score 设为指数退避值(如 60s → 300s → 900s)
  • 永远不要在重试逻辑里用 time.time(),要用上一次失败时刻 + delay,否则时钟漂移会导致重试时间不准
  • 加个最大重试次数字段,存进 value 里(比如 JSON 字符串),超过就丢进死信队列 dlq:delay

Python 用 redis-py 连接时,socket_timeout 和 health_check_interval 必须设

延时队列对连接稳定性极其敏感。worker 长期空闲时,中间网络设备(NAT、负载均衡器)可能静默断开 TCP 连接,但 client 还以为连着,下次 zrangebyscore 就卡住或报 ConnectionError。

这不是代码逻辑问题,是连接管理没配好。

  • socket_timeout=5 强制命令超时,避免 hang 死
  • health_check_interval=30 让 client 每 30 秒发个 PING 探活,自动重连断开的连接
  • 别用 ConnectionPool 默认配置——它的 max_connections 是 2**31-1,看似无限,实则会撑爆文件描述符
  • 示例初始化:
r = redis.Redis(connection_pool=redis.ConnectionPool(
    host='localhost',
    port=6379,
    db=0,
    socket_timeout=5,
    health_check_interval=30,
    max_connections=20
))

Redis ZSET 延时队列真正难的不是怎么塞数据,而是怎么让时间戳可靠、怎么防并发误取、怎么把失败隔离清楚。这三个点里任意一个没压住,线上就会出现任务丢失、重复、堆积。尤其时间戳,最容易被当成“小问题”跳过,结果查三天才发现是时区或精度搞错了。

热门AI工具

更多
立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2315

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3802

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1256

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

4399

2025.09.10

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1918

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

3144

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6364

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

6469

2023.11.24

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

80

2026.11.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn