0

0

Python Redis ZSET 实现的延时队列

舞姬之光

舞姬之光

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

|

500人浏览过

|

来源于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免费学习笔记(深入)”;

SoundRaw AI
SoundRaw AI

面向创作者的 AI 音乐生成器,只需选择情绪、流派和长度,SoundRaw AI就能为你生成优美的歌曲。

下载
  • 用 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_timeouthealth_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工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

442

2023.08.07

json是什么
json是什么

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

544

2023.08.23

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

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

322

2023.10.13

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

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

81

2025.09.10

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

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

573

2023.08.03

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

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

216

2023.09.04

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

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

1553

2023.10.24

字符串介绍
字符串介绍

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

640

2023.11.24

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

660

2026.02.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 4.4万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.6万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号