如何高效实现对events表直播事件的第三方API定时顺序轮询?
高效轮询直播事件API的实现方案
核心思路
基于Redis构建任务调度与状态管理体系,结合数据库的事件生命周期控制,确保按顺序执行第三方API请求、严格遵守15分钟最小轮询间隔,直到事件结束。整体逻辑是带时间调度的任务队列,更贴合你的业务需求。
Redis组件选型与落地
- 有序集合(Sorted Set):
pending_polls
用事件id作为member,下次轮询的时间戳作为score。利用ZRANGEBYSCORE可以快速筛选出当前需要执行的任务,且天然按时间排序,完美匹配"按顺序执行"的要求。 - 哈希表(Hash):
event:status:{event_id}
存储单个事件的关键状态:last_poll_time:上次API请求的时间戳,用于校验15分钟间隔is_finished:标记事件是否已结束(0=未结束,1=已结束)retry_count:API请求失败后的重试次数(用于异常处理)
具体执行流程
1. 任务初始化
- 从
events表查询所有满足start_time <= 当前时间 < end_time的直播事件,排除已标记结束的记录。 - 对每个事件,计算首次轮询时间(可设为当前时间或
start_time后),通过ZADD pending_polls {首次轮询时间戳} {event_id}批量加入有序集合。 - 同时用
HSET event:status:{event_id} last_poll_time 0 is_finished 0 retry_count 0初始化状态哈希表。
2. 轮询调度与执行
启动一个常驻进程(或用定时任务框架,需保证单实例避免并发冲突),每隔1分钟执行一次以下逻辑:
- 执行
ZRANGEBYSCORE pending_polls -inf {当前时间戳},取出所有到期的任务。 - 遍历每个
event_id:- 先通过
HGET event:status:{event_id} is_finished检查事件状态,若为1则跳过,并执行ZREM pending_polls {event_id}移除任务。 - 校验
last_poll_time,确保距离上次请求已超过15分钟,避免重复触发。 - 按顺序调用第三方API获取分析数据,处理并存储结果。
- 执行
HSET event:status:{event_id} last_poll_time {当前时间戳}更新请求时间。 - 计算下次轮询时间:
当前时间戳 + 15*60。若该时间 <= 事件end_time,则用ZADD pending_polls {下次轮询时间戳} {event_id}重新入队;否则执行HSET event:status:{event_id} is_finished 1并移除任务。
- 先通过
3. 异常处理
- 若API请求失败,先执行
HINCRBY event:status:{event_id} retry_count 1递增重试次数。 - 若重试次数未超过阈值(比如3次),将下次轮询时间设为
当前时间 + 5*60(短间隔重试),重新加入有序集合。 - 若重试超限,标记事件为异常状态(可新增
is_error字段),不再继续轮询,触发告警通知。
数据库联动优化
- 每小时执行一次同步任务:从
events表查询新增的直播事件,加入Redis任务队列,避免遗漏刚创建的事件。 - 当事件在数据库中被手动标记结束时,同步更新Redis中的
is_finished为1,并移除对应任务。
性能优化
- 单进程顺序执行:由于第三方API要求按顺序执行,单进程处理任务是最稳妥的方式。若后续需要扩容,可按事件id分段,用多个进程各处理一段,保证段内顺序执行。
- Redis批量操作:初始化任务时用
ZADD批量添加,减少网络往返开销。 - 过期清理:每天执行一次清理任务,删除
is_finished=1的事件哈希表记录,释放Redis内存。
内容的提问来源于stack exchange,提问作者Rahul Patel
相关产品推荐
相关产品推荐

