百万级定时任务如何设计?有什么好的框架呢?

2019-03-05 00:02:37 +08:00
 nezhaxiaozi1015

我这现在有个需求就是我们的产品可以让我们的用户预约一个时间来执行一次或者周期性的执行。

在看了 TBSchedule 和 Elastic-job 之后好像他两不适合创建百万用户级的子任务。虽然执行的功能也就两个,但是用的预约量可能是百万级的。

之后还想过通过 mysql 扫表的方式来实现,但是这种方式太暴力了。有没有什么好的方式呢?

7368 次点击
所在节点    程序员
37 条回复
binux
2019-03-05 00:06:05 +08:00
sorted queue 按最近执行时间排序
jokerlee
2019-03-05 00:06:36 +08:00
mysql 扫表其实挺好的,简单好维护,时间加上索引就行
jadec0der
2019-03-05 00:10:47 +08:00
看你这个需求好像执行频率不太频繁,如果是每分钟 N 个任务,可以用
00:01 - 任务 1, 任务 2, 任务 3
00:02 - 任务 4, 任务 5, 任务 6
的结构保存任务,每分钟唤起一次,拿到所有任务然后执行。

如果很密集,一小时几百万个任务,可以参考游戏常用的时间轮算法。
nezhaxiaozi1015
2019-03-05 00:12:27 +08:00
@binux 主要我的预约任务队列需要频繁的进行增加和删除操作,感觉单纯的有序队列还是不太适合
jokerlee
2019-03-05 00:12:47 +08:00
起一个进程不停查预约时间早于当前时间的行,扫到以后 update 状态然后进程内处理或者扔到消息队列里
nezhaxiaozi1015
2019-03-05 00:15:12 +08:00
@jadec0der 我这个执行频率不算高,主要是用户的预约点可能都会集中在早高峰和晚高峰出行的时间段,早晚高峰的任务量肯定会达到百万级的
jokerlee
2019-03-05 00:16:18 +08:00
如果只是做简单处理,或者转发,单机基本就够了。考虑高可用可以起多个进程并发扫,以 update 状态 sql 的 affected rows=1 来判断抢没抢到
jokerlee
2019-03-05 00:17:38 +08:00
如果在考虑 mysql 扩展性,分库分表就行了
nezhaxiaozi1015
2019-03-05 00:17:44 +08:00
@jokerlee 扫表的话,我这边也是在想怎么尽量把扫表的量压缩到最小,毕竟总的预约量还是很大的,但是在某一个时间段的预约量还是可控的。
jokerlee
2019-03-05 00:18:40 +08:00
@nezhaxiaozi1015 limit 行数就行
reus
2019-03-05 00:18:51 +08:00
用 PostgreSQL,时间建索引,然后多个线程
SELECT ...
FROM jobs
WHERE time < now()
ORDER BY time ASC
LIMIT 100
FOR UPDATE SKIP LOCKED
瓜分任务执行,一点问题都没有。关系数据库发展几十年了,总不至于连这点能力都没有。

MySQL 要 8.0 才有 SKIP LOCKED。
nezhaxiaozi1015
2019-03-05 00:20:15 +08:00
@jokerlee 嗯嗯,现在的想法也是开个现场任务不断的扫表,但是我不想扫全表
jokerlee
2019-03-05 00:22:09 +08:00
@nezhaxiaozi1015 假如同一秒最多有 n 个预约,一次扫 m 行,每 t 秒扫一次的话,不考虑处理耗时,满足 m/t > n 就不会延迟
jokerlee
2019-03-05 00:24:45 +08:00
@nezhaxiaozi1015 当然不用扫算表 select * from tasks where start_time < current_timestamp() and status=0
br00k
2019-03-05 00:27:54 +08:00
不知道时间范围,用延迟消息不知道能不能满足。😂
nezhaxiaozi1015
2019-03-05 00:32:37 +08:00
@reus 谢谢指点,学习一下
nezhaxiaozi1015
2019-03-05 00:35:16 +08:00
@jokerlee 同一秒的预约量实际上是不可控的,只知道有早晚高峰😂
nezhaxiaozi1015
2019-03-05 00:38:38 +08:00
@br00k 延迟队列,是可以,但是中间要是有用户修改或者删除预约那就麻烦了,还得存一下预约信息,消费的时候判断一下
j2gg0s
2019-03-05 00:38:55 +08:00
mysql 唯一选择,保证任务不丢,轻松扛住你的 QPS,把时间精度控制下
百万级这个形容词可以具体点
jokerlee
2019-03-05 00:40:27 +08:00
@nezhaxiaozi1015 再多也有个设计上限,一秒百万够不够,如果要一秒百万不 lag,就分一千张表,多起进程分开扫就完事了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/541092

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX