gpt4 book ai didi

spring - 使用zookeeper在集群中调度任务

转载 作者:行者123 更新时间:2023-12-01 06:05:07 26 4
gpt4 key购买 nike

我们使用 Spring 来运行在单节点上运行良好的计划任务。我们希望在 N 个节点的集群中运行这些计划任务,以便在一个时间点最多由一个节点执行任务。这是针对企业用例的,我们可能期望多达 10 到 20 个节点。

我研究了各种选择:

  • 使用 Quartz,它似乎是在集群中运行计划任务的流行选择。缺点:我想避免的数据库依赖。
  • 使用 zookeeper 并始终仅在领导者/主节点上运行计划任务。缺点:任务执行负载没有分布
  • 使用 zookeeper 并在所有节点上调用计划任务。但是在任务运行之前获取分布式锁并在执行完成后释放。
    缺点:所有节点上的系统时钟应该同步,如果应用程序过载导致系统时钟漂移,这可能是一个问题。
  • 使用zookeeper,让主节点按照时间表继续生成任务,并将其分配给随机 worker 。如果先前的计划任务尚未处理,则不会分配新任务。缺点:这似乎增加了太多的复杂性。

  • 我倾向于使用 #3,这似乎是一个安全的解决方案,假设 zookeeper 集成节点运行在一个单独的集群上,系统时钟使用 NTP 同步。这也是假设如果系统时钟同步,那么所有节点都有平等的机会获得锁来执行任务。
    编辑:经过深思熟虑后,我意识到这可能不是一个安全的解决方案,因为系统时钟应该在运行计划任务的节点之间同步,而不仅仅是 Zookeeper 集群节点。我说不安全是因为运行任务的节点可能因 GC 暂停和其他原因而过载,并且时钟可能不同步。但我再次认为这是分布式系统的标准问题。

    您能否告知我对每个选项的理解是否准确?或者可能有比列出的选项更好的方法来解决这个问题。

    最佳答案

    嗯,你可以改进 #3 像这样。

    Zookeeper提供观察者 .也就是说,您可以在给定的 ZNode 上设置观察者(例如在路径 /some/path 处)。集群中的所有节点都在监视同一个 Znode。每当节点认为(按计划或以任何方式)它现在应该运行计划任务,

  • 首先它创建一个 PERSISTENT_SEQUENTIAL /some/path下的子节点(所有节点都在观看)。此外,您可以根据需要设置该节点的数据。可能是 json 字符串 指定有关要运行的任务的详细信息。新的 ZNode 路径看起来像 /some/path/prefix_<sequence-number> .
  • 然后,集群中的所有节点都会收到有关创建的子节点的通知。然后所有这些都获取新创建的 ZNode 的数据并解码任务。
  • 现在,每个节点都尝试获取分布式锁。谁先获得它就可以执行它。一旦执行,该节点应该报告(比如通过在 /some/path/prefix_<sequence-number> 下创建一个名为 success 的新 ZNode ),该任务已执行。然后释放锁。
  • 每当节点尝试执行任务时,在尝试获取分布式锁之前,它应该检查该 ZNode 是否已经拥有 success子节点。

  • 这种设计通过检查名称为 success 的子节点来确保没有任务运行两次。在给定的 ZNode 下创建以通知启动任务。

    我已将上述设计用于企业解决方案。实际上对于分布式命令框架;-)

    关于spring - 使用zookeeper在集群中调度任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41157930/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com