轮询数据库的替代方案?

时间:2009-04-24 18:42:26

标签: polling

我有一个如下工作的应用程序:Linux机器为客户生成28种不同类型的信件。这些字母必须以.docx(Microsoft Word格式)发送。秘书维护MS Word模板,必要时自动使用。不能使用MS Word进行更改。

为了协调所有这些,文档作业被放入数据库表中,并且在每台Windows机器上运行的python程序经常轮询数据库,锁定作业并根据需要运行它们。

我们使用中央数据库表来获取作业信息,以协调不同的状态(“新”,“处理”,“完成”,“打印”)......以及提供准确的状态信息。

无论如何,我不喜欢客户经常轮询数据库,因为他们大部分时间都没有工作。客户每隔5秒钟就会出现一次。

为了避免轮询,我有点想要广播“有一些工作要做”或“检查你的数据库是否有一些工作要做”的消息发送到所有客户端机器。

我认为某种发布/订阅消息队列可以胜任这项工作,但我不希望任何大量额外的复杂性。

是否有零或接近零的配置/维护软件才能实现这一目标?有什么选择?

X

4 个答案:

答案 0 :(得分:6)

是否有任何客观证据证明服务器上有任何重大负载?如果它有效,我会确定这里真的有问题需要解决。

让一切运行得如此顺利以至于你正在寻找可能只会改进的东西一定很好!

答案 1 :(得分:3)

  

是否有零或接近零的配置/维护软件才能实现这一目标?有什么选择?

可能,但是您在配置和实施时节省的费用可能会比您的轮询服务更能影响性能。 SQL Server并不是真正做到推送(不管怎么说都不容易)。有些东西可以用来推送数据(复制服务,日志传送 - icky东西),但它们会比简单的轮询服务更复杂,需要更多的资源。一些选项是:

  1. 使用命令行调用运行可执行文件的某种触发器(sp_cmdshell)

  2. 使用SQL Server可以打开并运行的COM对象

  3. 使用SQL代理作业运行VBScript(再次被视为“轮询”)

  4. 考虑到你已经做的事情要简单得多,这些选项有点荒谬。

    如果您担心轮询服务使用太多周期或其他事情 - 您可以随时将其限制回来 - 每分钟,每10分钟轮询一次,甚至每天一次轮询可能更合适 - 这将是一个商业决策所以去问一下业内人员需要多快。

    简单的民意调查服务相当普遍,因为它们很简单。此外,它们还具有低开销,远程稳定和容错性。不好的一面是,如果不加以严密控制,他们可以将数据库锤入灰尘。

答案 2 :(得分:3)

消息队列可能运行良好,因为它们通常设置为能够阻塞一段时间而不浪费资源。但是对于MySQL,我认为这不是一个选择。

如果您只想减少数据库的负载,可以创建一个包含单行的表:最新的作业ID。然后客户端只需要将它与它们的最后一个ID进行比较,看看它们是否需要针对真实表运行完整的轮询。如果这是一个问题,这种方式应该大大减少开销。

答案 3 :(得分:1)

与Postgres和SQL Server(或像CouchDb这样的对象存储)不同,MySQL不会发出数据库事件。但是,您可以使用一些编码模式来模拟它。

如果您希望监视一个或多个表,则可以在这些表上创建触发器,这些表将行添加到记录要处理的事件队列的“更改”表中。您的触发器会过滤您关注的数据更改子集,并在更改表中为您要执行的每个事件创建记录。由于此模式队列持久事件,即使处理这些事件的工作人员中断,它也能正常运行。

您可能认为MyISAM是更改表的最佳选择,因为它主要执行写操作(如果您不需要在数据库服务器中断之间保留事件,则甚至是MEMORY)。但是,请记住,Memory和MEMORY以及MyISAM都只有全表锁,因此当执行插入MEMORY和MyISAM表时,InnoDB表上的触发器可能会遇到瓶颈。如果您使用ON DELETE CASCADE与另一个InnoDB表(要求两个表使用相同的引擎),您可能还需要InnoDB作为更改表。

您也可以使用SHOW TABLE STATUS检查更改表的上次更新时间,以检查是否有要执行的操作。 InnoDB表的此功能wont work

这些文章更深入地描述了在MySQL中实现队列的一些替代方法,甚至可以避免轮询!