2

我有两个进程在各自的 JVM 中运行(比如节点 A 和 B)。它们连接到单个 ZooKeeper 服务器以协调任务执行。任何一个节点(A 或 B)都应该scheduled task (freq 1 minute)一次执行 a,而不是同时执行。此外,如果 A 失败,则 B 应在下一个预定时间接管执行任务。

以下是问题

节点 A 赢得了比赛并在 ZooKeeper 上创建了一些临时节点,以表明它已经开始执行任务。一旦 A 开始执行任务,它就会失去与 ZooKeeper 的连接,因此 ZooKeeper 会在一段时间后删除临时节点。由于意外的更大数据量,执行超过了 1 分钟边界。现在当 B 醒来时,它不会看到 A 之前创建的任何临时节点。在没有该节点的情况下,B 认为没有其他节点正在执行该任务,并且它也开始与disconnectedA 并行执行该任务,这是错误的。A 或 B 应该运行该任务。

我更喜欢 A 完成启动的任务,即使它没有连接到 ZooKeeper 并且 B 在 A 完成任务之前不会并行运行。

我正在使用org.I0Itec.zkclient.ZkClient客户端库。除了自定义heartbeat机制,还有其他解决方案吗?

4

2 回答 2

1

另一种解决方案是创建一个目录,其中包含正在执行的所有当前任务。当节点 A 执行完任务 T 时,节点 B 已经开始执行任务 T。现在,您可以尝试杀死节点 B 并提交节点 A 产生的所有更改。这是推测执行原理的一种变体。如果节点 A 成功执行任务,您可以终止节点 B 或放弃该节点所做的所有更改。

于 2015-07-26T00:01:33.660 回答
0

如果设置更高的会话超时时间,B 创建的临时节点不会被删除,B 也不会执行任务。

再具体一点,

  • 如果您知道线程执行任务可以花费的最长时间,则将该最长时间设置为会话超时
  • 否则根据平均执行时间、p-90 或其他一些启发式方法决定超时
于 2015-07-23T20:28:22.960 回答