2014-04-01 143 views
4

场景:可扩展的作业队列系统

TL; DR - 我需要根据未来的时间戳,而不是将其插入

顺序触发工作队列系统我有一个条目的MySQL数据库,用于详细说明需要执行的特定事件(主要包括一系列算术计算和数据库插入/更新),并基于时间戳进行精确排序。条目插入的时间和事件“执行”的时间没有关联,并且由外部因素决定。该表还包含第二列毫秒,这增加了时间精度。

这表是工作“队列”,这将包含设置为从几秒钟之间的任何地方在未来执行几天条目的一部分,并可能有多达数千个条目的添加每一秒。队列需要不断解析(每秒) - 也许在这第二次做一个选择已经过期的所有的时间标记,并在毫秒排序,然后执行由项的详细每个事件。

问题

目前后端完全用PHP编写的Apache服务器上使用MySQL(即标准LAMP架构)。现在,我能想到的,以实现我指定什么的唯一方式是编写一个自定义的PHP作业队列脚本,将做分析和执行,每循环使用第二this method。我没有其他的工作系统可以根据指定的时间戳/毫秒而不是输入时间对作业进行排队。

然而,即使在纸上,这种方法听起来也是不可行的CPU - 我必须每秒钟执行一次巨大的MySQL查询,并为每个检索行执行某种函数,并有可能运行超过一秒的执行时间将开始在解析时间中引入延迟并搞乱循环脚本。

我当然试图创建一个解决方案,将可扩展应该有系统,此解决方案悲惨的失败了,因为它会继续落后作为条目的数量变大上交通繁忙。

的问题

我宁愿坚持标准的LAMP架构,但没有任何其他的技术,我可以很好地集成到能更好地处理一下,我试图堆栈在这里做?

是否有另一种方法来完全准确地在指定的未来日期的触发事件没有凌乱摆弄随着不断的队列检查?

如果没有上述选项都适合,有没有循环更好的方式在后台PHP脚本?在最坏的情况下,我可以接受很长的执行时间,并在多个“工作人员”之间分配任务。

更新

的RabbitMQ是一个很好的建议,但不幸的是因为它“到期”不尽快执行任务 - 它必须先通过一个队列,等待了任何任务面前说尚未到期。到期时间的范围在几秒到几天之间,并且每次添加新事件时都需要对队列进行排序,因此到期时间总是在队列中排序。就我在RabbitMQ中知道的情况而言,这是不可能的,而且听起来也不是很有效。是否有替代或程序修复?

回答

0

有时,制作一个方形钉适合圆孔需要很多努力。尽管使用MySQL来创建队列可能会很有效,但它的扩展变得非常棘手。我建议这可能是RabbitMQ的一个机会。

基本上,你会设置一个消息队列,你可以把事件放进去。然后,您将有一个“扇出”架构,让您的员工处理每个队列。每个工作人员都会监听队列并检查是否需要处理特定事件。我想像一下"Work Queues""Routing"技术的组合可以在可扩展和可靠的方式下实现你正在寻找的东西。

我想象的作品是这样一个系统:

  1. 产卵工人听队列,使用路由键消减他们多少消息得到
  2. 每个工人检查消息,看是否他们现在要执行
  3. 如果要执行消息,执行它并确认 - 否则,重新发送消息以供将来处理。有一些simple techniques可用于此。

随着您需要更多规模,您需要添加更多工作人员。 RabbitMQ非常强大,并且当您最终限制队列服务器时容易集群。还有其他基于云的排队系统,如Iron.IOStormMQ

+1

我做了一些研究,RabbitMQ的,直到我碰到这次来到它看起来非常有前途:http://www.rabbitmq.com/ttl.html(注意事项) 。我需要设置每条消息的TTL来定义执行任务的时间,但正如我所提到的,它可能从几秒到几天不等。我需要在计时器到期时立即执行任务,但它看起来像rabbitMQ将等待队列首先弹出。我需要一些方法对队列进行排序,以便首先到期的任务位于队列头部,并按顺序弹出。有针对这个的解决方法吗? – user1334061

+0

可能不是,我试图如何处理它:让消息本身有执行时间。接收消息的作业可以立即确认,读取时间,如果现在或过去,执行。如果是将来,请重新派遣同一时间,以便其他工作人员可以拿起它。我会让所有工作人员在抓取和重新发送(1-100毫秒)之间睡眠一段时间,这样您就不会忙于等待队列服务器。 – Sam