2016-10-07 29 views
1

我需要设计一个分布式系统,调度程序将任务发送给多个节点中的工作人员。每个任务都分配一个ID,并且可以多次执行,由调度程序调度(通常每小时一次)。确保单个任务实例正在运行的分布式工作人员

我唯一的要求是,具有特定ID的任务不应该在两次由集群同时执行。我可以想象一个设计,其中调度程序为每个任务ID保存一个锁并将任务发送给适当的工作人员。一旦工作人员完成锁定应该被释放,调度器可能再次安排。

我应该我的设计包括以确保这一点。我担心任务发送给启动任务的工作人员,但未能通知调度人员。

什么是此方案中的最佳实践,以确保只有一个工作的一个实例是在同一时间总是执行?

回答

1

您可以使用实现共识协议的解决方案。假设 - 例如 - 群集中的所有节点都可以使用Raft protocol进行通信。因此,每当节点X想要开始处理任务Y时,它将尝试提交消息X starts working on Y。一旦这些消息被提交到日志中,所有节点将以相同的顺序在日志中看到所有消息。

当节点X结束或中止它会尝试提交X no longer works on Y,以便其他节点可以开始/继续工作任务。

是可能发生的两个节点(X和Z)可以尝试提交他们的同时开始邮件,然后日志会是这个样子:

... 
N-1: ... 
N+0: "X starts working on Y" 
... 
N+k: "Z starts working on Y" 
... 

但因为没有X no longer works on Y消息在N + 0和N + k条目之间,每个节点(包括Z)都知道Z不能在Y上开始工作。

剩下的唯一问题是如果节点X从集群中分割出来,试图犯下我认为存在的X no longer works on Y完美的解决方案。

解决办法可能是X会尝试定期提交消息X still works on Y at time T,并且如果在某个阈值持续时间内没有将这样的消息提交到日志中,那么集群会认为没有人再继续处理该任务。

有了这个工作,但是周围,你会允许两个或多个节点将在同一个任务(分区节点X和超时后拿起任务了一些新的节点)工作的可能性。

0

一番彻底搜查后,我得出的结论,这个问题可以通过一个名为fencing方法来解决。

实质上,当您怀疑某个节点(worker)发生故障时,确保它不会损坏系统其余部分的唯一方法是提供一个阻止节点访问您所需的共享资源的篱笆保护。这必须是一个激进的方法,例如重置运行失败进程的计算机或设置阻止进程访问共享资源的防火墙规则。一旦篱笆就位后,您就可以安全地破坏失败进程持有的锁,并开始一个新进程。

相关问题