【问题标题】:Using MySQL as a job queue使用 MySQL 作为作业队列
【发布时间】:2011-10-25 05:34:41
【问题描述】:

我想将 MySQL 用作作业队列。多台机器将生产和消耗工作。需要安排工作;有些可能每小时运行,有些每天运行,等等。

看起来相当简单:对于每个作业,都有一个“nextFireTime”列,并让工作机器使用 nextFireTime 搜索作业,将记录的状态更改为“inProcess”,然后在作业时更新 nextFireTime结束。

当一个工人默默地死去时,问题就出现了。它将无法更新 nextFireTime 或将状态设置回“空闲”。

不幸的是,作业可能会长时间运行,因此无法选择寻找已在进程中时间过长的作业的 reaper 线程。没有可用的超时值。

任何人都可以提出一种可以正确处理不可靠工作机器的设计模式吗?

【问题讨论】:

  • 艰难的。是否可以要求长时间运行的作业在更新时定期更新“仍处于状态”列?并要求每 X 分钟发生一次?然后收割者可以说“如果你超过 X 分钟而没有更新,那就敲吧!”
  • 或者更好的设计可能是让作业队列本身以某种方式查询作业以确定它们的状态。 (一种侦听器模型。)作业必须知道如何响应状态查询。
  • 是的,我想到了。有点像心跳信号。工业控制器就是这样做的。这是可能的,但这意味着我所有的工作处理人员都必须有某种内部循环来进行更新。不是一个理想的解决方案。
  • 已经有像 RabbitMQ 这样完善的任务队列服务器。为什么不使用其中之一,而不是重新发明轮子?
  • 这不是您问题的答案,但请阅读这篇文章:engineyard.com/blog/2011/…

标签: mysql algorithm queue job-scheduling


【解决方案1】:

可能是这样

当工作人员获取作业时,它可以将其进程 ID 或另一个唯一 ID 添加到作业中的字段

然后在另一个表中,每个工作人员不断更新他们还活着的值。更新“我还活着”字段时,您检查所有其他“上次工人显示生命迹象”。如果某个工作人员超出限制,请找到它正在处理的所有工作并重置它们。

换句话说,看门狗在工作进程而不是作业本身上工作。

【讨论】:

    【解决方案2】:

    使用 MySQL 作为作业队列通常会以痛苦告终,因为它非常不适合 RDBMS 的通常目标。用户“toong”已经链接到https://www.engineyard.com/blog/5-subtle-ways-youre-using-mysql-as-a-queue-and-why-itll-bite-you,其中有很多有趣的事情要说。不可靠的工人只是问题之一。

    处理作业分配的系统有很多很多,它们的主要特点是其排队和调度功能的复杂性。在简单的 FIFO 端是 Resque、Celery、Beanstalkd 和 Gearman;在复杂的一端是 GridEngine、Torque/Maui 和 PBS Pro。如果您可以容忍对 Amazon 服务的依赖,我强烈推荐新的 Amazon Simple Workflow 系统(我相信它确实要求您使用 EC2)。

    对于您最初的问题:现在我们正在实施一个每个节点的监督者,它可以判断节点的作业是否仍然处于活动状态,如果是,则将心跳发送回作业监视器。这很痛苦,但是当您正在发现并将继续发现时,有很多细节和错误案例需要管理。不过,大多数情况下,我必须鼓励您通过了解这个领域并从一开始就正确构建系统来帮自己一个忙。

    【讨论】:

      【解决方案3】:

      一种选择是确保作业是幂等的,并允许多个工人开始一项给定的作业。哪个工人完成工作,或者是否有多个工人完成工作都没有关系;因为作业的设计方式可以优雅地处理多个完成。也许工人竞相提供结果,而失败者发现将保存结果的槽已经满了,所以他们就放弃了。

      另一种选择是不要做大工作。将长时间运行的作业分解为中间步骤,如果作业花费的时间超过(例如)1 分钟,将中间结果存储为新作业(以某种方式与旧作业的链接),以便新作业可以再次排队再做一分钟的工作。

      【讨论】:

      • 是的,这是可能的。重叠的工作可能没问题。
      猜你喜欢
      • 2013-05-08
      • 1970-01-01
      • 2021-09-16
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-11
      相关资源
      最近更新 更多