如何设计分布式作业调度器? [关闭]

Posted

技术标签:

【中文标题】如何设计分布式作业调度器? [关闭]【英文标题】:How to design a distributed job scheduler? [closed] 【发布时间】:2015-01-09 12:03:19 【问题描述】:

我想设计一个作业调度器集群,其中包含几个主机来做 cron 作业调度。例如,一个需要run every 5 minutes的作业被提交到集群,集群应该指出下一次运行哪个主机,确保:

    容灾:如果不是所有主机都关闭,作业应该会成功触发。 有效性:只有一个主机可以触发下一次作业运行。

由于容灾,作业无法绑定到特定主机。一种方法是所有主机轮询数据库表(当然有锁),这保证只有一个主机获得下一个作业运行。既然经常锁表,有没有更好的设计?

【问题讨论】:

【参考方案1】:

为此使用Quartz framework。它具有类似 cron 的语法,可以集群,并且集群中的主机一次只能执行一项工作。如果主机或作业失败,另一台主机将重试挂起的作业。

【讨论】:

Quartz 是一个漂亮的做作业调度的框架,它也支持分布式,不过我想知道 Quartz 的集群是怎么设计的。 coderz,带有集群的石英像简单的石英配置一样工作。您只需设置 org.quartz.jobStore.isClustered = true,将石英表添加到数据库中,石英将负责容灾和仅运行一次。有关石英集群如何工作的更多信息,您可以阅读quartz-scheduler.org/generated/2.2.1/html/qs-all/#page/…【参考方案2】:

我搜索了 Dkron(分布式作业调度系统)。它有rest api,看起来不错。我打算尝试使用它 Dkron site

【讨论】:

我们从头开始构建了一个。你可以在这里阅读文章medium.com/myntra-engineering/…【参考方案3】:

很久以前,当使用软盘进行同步时,我确实需要这样的东西。您应该清楚三件事,这似乎很简单,但在分布式环境中却没有:-)

“同步部分” 如果你得到一个净拆分,这意味着你的集群被分成两个单独的部分,它们可以在这些部分内部进行通信,但不能在两个部分之间进行通信,那么“只触发一次作业”只能在每个同步部分中获取。

“灾难” 如果几乎所有时间所有计算机都启动并运行并且很少有一台失败,并且两台失败几乎是不可想象的,这是完全不同的事情,而不是每台主机只在部分时间运行,连接不稳定,或者同步是通过拨号连接或软盘完成。如果您甚至想处理净拆分,它就会变得非常复杂。 如果你想处理恶意主机,你还有另一个问题。

“有效性” 每个作业只触发一次...您必须比作业触发间隔更快地同步。

编辑:调度任务设计的提示。我有一个大文本文件,其中包含行。每一行都是一个作业任务,从作业类型开始,然后是执行时间,然后是命令,最后但并非最不重要的是可选的重复任务的重新提交间隔。同步意味着合并。已执行的任务被删除。如果重新提交,则插入或附加新任务。

在理想的世界中,每个主机都始终与其他主机相连,我会实现类似令牌环的东西。如果没有主控,则由主机选择一个,主控预计会安排一切,直到他有一段时间没有发送听到的心跳。如果有两个主人,他们协商其中一个成为主人(也许更低的MAC地址......随便)。

如果您必须处理恶意主机,您可以使用一些拜占庭 gerenals-problem 解决方案。主人的选择已经很好地抵御了恶意主机。只需一点点 rsa-krypto,选定的 master 就可以对每个命令进行签名,重新发送攻击可以用时间戳或不断增长的索引来处理......瞧。

仅作为一个老程序员的故事,不适合今天一切都与互联网世界相连: 大约 20 年前,我的最大问题是,主机同步从每小时一次和每天一次到每周一次或每月一次。所以解决方案是使用不同的命令: 1. 在给定日期在每台主机上执行(对于同步来说,这在未来已经足够远了) 2. 在主机上执行,其中“whoami”包含某个子字符串。 3. 以很小的概率在随机主机上执行,并向所有其他主机发送确认已执行完毕。

如果同步比执行概率快得多,则第三个命令类型会执行类似“仅触发一次”的操作。如果您知道同步间隔,它不需要主从架构,并且运行良好。

【讨论】:

【参考方案4】:

我不确定如何设计一个,但有一些开源产品可以作为示例。一个是上面提到的Quartz scheduler。

但是,显然,WallmartLabs 已经评估了 Quartz,发现它不够好,因此创建并开源了一个更好的(在他们看来)替代它,称为 BigBen。也许你也可以看看那个。

【讨论】:

感谢分享 BigBen,好文章!【参考方案5】:

如果您可以使用 AWS Web 服务,请考虑使用 AWS Simple Workflow Service。与 Quartz 之类的东西相比,它的好处是它不依赖于您必须托管的数据库,并且它可以提供比调度更多的功能。例如,如果由于任何原因无法进行调度,它可以运行一些活动来修复您的集群或寻呼您。 Here is an example 的 cron 工作流程。

【讨论】:

是的,另一个好方法!虽然我想知道框架是如何设计的。 temporal.io 是基于 AWS Simple Workflow Service 理念的开源解决方案。【参考方案6】:

查看运行在 Mesos 之上的 Chronos (https://mesos.github.io/chronos/) - (https://mesos.apache.org/) 资源调度程序。

【讨论】:

请用更多细节来证实你的答案,而不是仅仅链接到外部网站 Mesos 是一个用于管理计算资源的系统,其中计算资源可以是脚本、Web 服务、hadoop/spark 作业等任何东西,并且它与语言无关。它知道集群中可用的物理资源(CPU、Mem 等),并可以根据可用资源的位置分配作业。 Chronos 在 Mesos 之上运行,并提供类似 cron 的调度功能,以便您可以调度重复性任务,并且它也与语言无关。 IE。 Chronos 安排并将您的作业提交给 Mesos,然后 Mesos 确定在哪个主机上运行它。

以上是关于如何设计分布式作业调度器? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

第五到七次作业总结

怎么优化hadoop任务调度算法

第一次作业:Linux 2.6.32的进程模型与调度器分析

面向对象5-7次作业总结

SGE作业调度系统的简单理解

quartz开源作业调度框架的使用