繁体   English   中英

如何安排数十万个任务?

[英]How to schedule hundreds of thousands of tasks?

我们有成千上万的任务需要以各种任意间隔运行,有些是每小时,有些是每天,等等。 这些任务是资源密集型的,需要分布在许多机器上。

现在,任务存储在具有“此时执行”时间戳的数据库中。 要查找需要执行的任务,我们在数据库中查询将要执行的作业,然后在任务完成时更新时间戳。 当然,这会导致数据库的大量写入负载。

据我所知,我们正在寻找一些东西,以设定的间隔将任务释放到队列中。 (然后工人可以从该队列中请求任务。)

大规模安排重复任务的最佳方法是什么?

尽管使用其他语言编写的组件(RabbitMQ?)没有问题,但我们在很大程度上使用Python是值得的。

更新:现在我们有大约350,000个任务,每半小时左右运行一次,有一些变化。 350,000个任务*每天48次,每天执行16,800,000个任务。

更新2:没有依赖项。 任务不必按顺序执行,也不依赖于以前的结果。

由于不需要ACID,并且您可以使用可能运行两次的任务,我根本不会在数据库中保留时间戳。 对于每个任务,创建[timestamp_of_next_run,task_id]列表并使用最小堆来存储所有列表。 Python的heapq模块可以为您维护堆。 您将能够以最快的时间戳非常有效地弹出任务。 当您需要运行任务时,使用其task_id在数据库中查找任务需要执行的操作。 任务完成后,更新时间戳并将其放回堆中。 (注意不要更改当前堆中的项目,因为这会破坏堆属性)。

仅使用数据库存储在崩溃和重新引导后仍将关注的信息。 如果重启后不需要这些信息,请不要花时间写入磁盘。 您仍然需要进行大量的数据库读取操作来加载有关需要运行的任务的信息,但读取比写入要便宜得多。

如果没有足够的RAM同时将所有任务存储在内存中,您可以使用混合设置,在接下来的24小时内(例如)将任务保留在RAM中,其他所有内容都保留在内存中。数据库。 或者,你可以用C或C ++重写代码,这些代码可以减少内存消耗。

如果您不想要数据库,则可以将下一个运行时间戳和任务ID存储在内存中。 您可以将每个任务的属性存储在名为[task_id] .txt的文件中。 您需要一个数据结构来存储所有任务,按内存中的时间戳排序,AVL树似乎可以工作,这是一个简单的python: http//bjourne.blogspot.com/2006/11/avl- tree-in-python.html 希望Linux(我假设您运行的是)可以处理目录中的数百万个文件,否则您可能需要在任务ID上进行哈希以获取子文件夹)。

您的主服务器只需要运行一个循环,从AVL树中弹出任务,直到下一个任务的时间戳在将来。 然后你可以睡几秒钟然后再开始检查。 每当任务运行时,您都将更新任务文件中的下一个运行时间戳并将其重新插入AVL树中。

当主服务器重新启动时,会有将所有任务id和下一次运行时间戳重新加载到内存中的开销,因此数百万个文件可能会很痛苦。 也许你只有一个巨大的文件,并为文件中的每个任务提供1K空间的属性和下一个运行时间戳,然后使用[task_id] * 1K来获得任务属性的正确偏移量。

如果您愿意使用数据库,我相信MySQL可以根据您描述的条件处理您丢弃的任何内容,假设您的主服务器上有4GB + RAM和RAID 0 + 1中的多个硬盘驱动器。

最后,如果你真的想变得复杂,Hadoop也可能会工作: http//hadoop.apache.org/

如果您担心写入,您可以使用一组服务器来分派任务(可以对服务器进行条带化以均衡负载)并让每个服务器向DB写入批量检查点(这样,您就不会有这么多写入查询)。 当然,如果调度服务器死了,你仍然需要编写才能恢复。

此外,如果时间戳上没有聚集索引,则可以避免在表的末尾出现热点。

350,000个任务*每天48次,每天执行16,800,000个任务。

要计划作业,您不需要数据库。

数据库用于更新的内容 此处可见的唯一更新是更改添加,删除或重新安排作业的计划。

Cron使用单个平面文件以完全可扩展的方式完成此操作。

将整个平面文件读入内存,开始生成作业。 定期检查fstat以查看文件是否已更改。 或者,更好的是,等待HUP信号并使用它重新读取文件。 使用kill -HUP通知调度程序重新读取文件。

目前还不清楚你要为什么更新数据库。

如果数据库用于根据作业完成确定未来的计划,那么单个数据库就是一个非常好的想法。

如果您正在使用数据库对作业历史进行一些分析,那么您将拥有一个简单的数据仓库。

  1. 在简单的平面日志文件中记录完成信息(开始时间,结束时间,退出状态,所有内容)。

  2. 处理平面日志文件以创建事实表和维度更新。

当有人有进行某些分析的冲动时,将平面日志文件的相关部分加载到数据集市中,以便他们可以进行查询和计数以及平均值等。

不要将每天17,000,000行直接记录到关系数据库中。 没有人想要所有这些数据。 他们想要摘要:计数和平均值。

为什么数十万而不是数亿? :邪恶:

我认为你需要无堆栈的python, http://www.stackless.com/ 由Christian Tismer的天才创造。

引用

Stackless Python是Python编程语言的增强版本。 它允许程序员从基于线程的编程中获益,而不会出现与传统线程相关的性能和复杂性问题。 Stackless添加到Python的线程是一种便宜且轻便的便利,如果使用得当,可以带来以下好处:改进的程序结构。 更易读的代码。 提高程序员的工作效率。

用于大型多人游戏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM