首页 文章

使用MySQL作为作业队列

提问于
浏览
2

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

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

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

不幸的是,作业可能会长时间运行,因此寻找已经处于过程中的作业的收割者线程不是一种选择 . 没有超时值可行 .

任何人都可以建议一个能够正确处理不可靠的 Worker 机器的设计模式吗?

3 回答

  • 4

    也许是这样的

    当工作者获取作业时,它可以将其process-id或另一个唯一ID添加到作业中的字段

    然后在另一个表中,每个工作者都会不断更新它们存活的值 . 当更新“我活着”字段时,你会检查所有其他“上一次 Worker 显示生命迹象” . 如果一个 Worker 超过限制,找到它正在处理的所有工作并重置它们 .

    换句话说,看门狗就是工作流程,而不是工作本身 .

  • 1

    使用MySQL作为一个工作队列通常会很痛苦,因为它已经链接到了https://www.engineyard.com/blog/5-subtle-ways-youre-using-mysql-as-a-queue-and-why-itll-bite-you,它有很多有趣的东西可以说 . 不可靠的 Worker 只是其中一个并发症 .

    有许多系统用于处理作业分配,主要区别在于其排队和调度功能的复杂程度 . 在简单的FIFO端,有像Resque,Celery,Beanstalkd和Gearman这样的东西;在复杂的一端是像GridEngine,Torque / Maui和PBS Pro这样的东西 . 如果您能够容忍依赖亚马逊服务,我强烈推荐新的Amazon Simple Workflow系统(我相信它不要求您使用EC2) .

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

  • 4

    一种选择是确保作业是幂等的,并允许多个工作人员启动给定的工作 . 哪个 Worker 完成工作,或者不止一个 Worker 完成工作并不重要;因为作业的设计方式可以优雅地处理多个完成 . 也许 Worker 竞相提供结果,失败者发现将保持结果的插槽已经满了,所以他们只是放弃它们 .

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

相关问题