我想设计一个作业调度器集群,其中包含几个主机来做 cron 作业调度。例如,一个需要run every 5 minutes
提交到集群的作业,集群应该指出下一次运行哪个主机,确保:
- 容灾能力:如果不是所有的主机都宕机了,这个作业应该可以成功触发。
- 有效性:只有一个主机可以触发下一个作业运行。
由于容灾的原因,作业无法绑定到特定的主机。一种方法是所有主机轮询数据库表(当然有锁),这保证只有一个主机获得下一个作业运行。既然经常锁表,有没有更好的设计呢?
我想设计一个作业调度器集群,其中包含几个主机来做 cron 作业调度。例如,一个需要run every 5 minutes
提交到集群的作业,集群应该指出下一次运行哪个主机,确保:
- 容灾能力:如果不是所有的主机都宕机了,这个作业应该可以成功触发。
- 有效性:只有一个主机可以触发下一个作业运行。
由于容灾的原因,作业无法绑定到特定的主机。一种方法是所有主机轮询数据库表(当然有锁),这保证只有一个主机获得下一个作业运行。既然经常锁表,有没有更好的设计呢?
为此使用Quartz 框架。它具有类似 cron 的语法,可以集群,并且集群中的主机一次只能执行一项工作。如果主机或作业失败,另一台主机将重试挂起的作业。
我用谷歌搜索了 Dkron(分布式作业调度系统)。它有rest api,看起来不错。我打算尝试使用它 Dkron 网站
很久以前,当使用软盘完成同步时,我确实需要这样的东西。您应该清楚三件事,这似乎很简单,但在分布式环境中却没有:-)
“同步部分”如果你得到一个网络分割,这意味着你的集群被分割成两个单独的部分,它们可以在这些部分内部进行通信,但不能在两个部分之间进行通信,那么“只触发一次作业”只能在每个同步部分中获取。
“灾难” 如果几乎所有时间所有计算机都启动并运行,并且很少有一台出现故障,而两台出现故障几乎是不可想象的,这是完全不同的事情,而不是每台主机只在部分时间运行,连接不稳定,或者同步是通过拨号连接或软盘完成的。如果您甚至想处理净拆分,它就会变得非常复杂。如果你想处理恶意主机,你还有另一个问题。
“有效性”每个作业只触发一次......您必须比作业触发间隔更快地同步。
编辑:调度任务设计的提示。我有一个大文本文件,其中包含行。每行都是一个作业任务,从作业类型开始,然后是执行时间,然后是命令,最后但并非最不重要的是可选的重复任务的重新提交间隔。同步意味着合并。已执行的任务被删除。如果重新提交已开启,则插入或附加新任务。
在理想的世界中,每台主机都始终与其他主机相连,我会实现类似令牌环的东西。如果没有 master,则由主机选择一个,并且 master 预计会安排一切,直到他有一段时间没有发送听到的心跳。如果有两个主人,他们协商其中一个成为主人(也许较低的MAC地址......无论如何)。
如果您必须处理恶意主机,您可以使用一些拜占庭 gerenals-problem 解决方案。主人的选择已经很好地抵御了恶意主机。只需一点点 rsa-krypto,选定的主机就可以对每个命令进行签名,重新发送攻击可以用时间戳或不断增长的索引来处理……瞧。
仅作为来自 onld 程序员的故事,不适用于今天,一切都始终连接到互联网世界: 大约 20 年前,我的最大问题是,主机从每小时和每天一次同步到每周或一次一个月。所以解决方案是使用不同的命令: 1. 在给定日期在每个主机上执行(对于同步来说,这在未来已经足够远了) 2. 在主机上执行,其中“whoami”包含某个子字符串。3. 在一个随机主机上执行,概率很小,并向所有其他主机发送确认,它已经执行完毕。
如果同步比执行概率快得多,则第三种命令类型会执行类似“仅触发一次”的操作。如果你知道同步间隔,它不需要主从架构,它工作得很好。
我不确定如何设计一个,但有一些开源产品可以作为示例。一种是上面提到的Quartz 调度器。
但是,显然,WallmartLabs 已经评估了 Quartz,发现它不够好,因此创建并开源了一个更好的(在他们看来)替代它,称为BigBen。也许你也可以看看那个。
如果您可以使用 AWS Web 服务,请考虑使用AWS Simple Workflow Service 。与 Quartz 之类的东西相比,它的好处是它不依赖于您必须托管的数据库,并且它可以提供比调度更多的功能。例如,如果由于任何原因无法进行调度,它可以运行一些活动来修复您的集群或寻呼您。这是 cron 工作流程的示例。
查看在 Mesos 之上运行的Chronos ( https://mesos.github.io/chronos/ ) - ( https://mesos.apache.org/ ) 资源调度程序。