数据库队列和队列处理

时间:2011-05-04 18:44:05

标签: azure queue azure-sql-database azure-queues

我目前正在为基于分布式事件的系统整合参考架构,其中事件使用普通旧表(没有SQL Server Service Broker)存储在SQL Server Azure数据库中。

将使用工作者角色处理事件,工作者角色将轮询队列以获取新的事件消息。

在我的研究中,我看到许多解决方案允许多个处理器处理队列中的消息。我遇到的很多模式的问题是当多个进程试图访问单个消息队列时管理锁定等的复杂性增加。

据我所知,传统的队列模式是从单个队列中拉出多个处理器。但是,假设可以按任何顺序处理事件消息,是否有任何理由不在队列与其队列处理器之间创建一对一关系,只是在不同队列之间进行负载平衡?

queue_1 => processor_1
queue_2 => processor_2

此实现避免了管理跨多个处理器的队列并发访问所需的所有管道。事件发布者可以使用任何负载平衡算法来决定将消息发布到哪个队列。

我在任何搜索中都没有看到这种实现的事实让我觉得我忽略了这种设计中的一个主要缺陷。

修改

这篇文章引发了一场关于使用数据库表作为队列与MSMQ,Azure队列等的争论。我理解我可以使用许多本机排队选项,包括Azure AppFabric中的持久消息缓冲区。我已经评估了我的选项,并确定SQL Azure表就足够了。我的问题是讨论针对单个队列使用多个处理器而不是每个队列使用一个处理器。

4 个答案:

答案 0 :(得分:5)

有关此主题的更详细讨论,请参阅Using tables as Queues。问题不仅在于您如何访问“队列”,还在于如何对其进行索引,聚集索引必须允许直接搜索下一行出列,否则您将不断陷入僵局。

您希望您的处理器竞争到同一个队列,通过扩展到不同的队列进行负载均衡是一种反模式。它会导致车队和人工延迟,其中您的项目排在后期处理器后面,但其他处理器是空闲且空闲的,因为他们的队列是空的。

答案 1 :(得分:1)

作为队列的表很容易做到。请在此处查看我的答案:SQL Server Process Queue Race Condition

答案 2 :(得分:1)

正如S.Lott所提到的,您可以使用消息队列机制。 MSMQ在Windows Azure中无法提供帮助,但Windows Azure已经具有持久的队列机制。您可以轻松设置每个辅助角色实例以读取一个(或多个)队列项。一旦读取了一个队列项,它就会在你指定的任何时间长度内“不可见”(如果没有指定时间,则为30秒)。队列消息最多可达8K,并且它们被认为是“持久的” - 所有Azure存储至少复制3次(与SQL Azure一样)。

虽然您可以实现gbn所描述的内容,但我真的认为在Windows Azure中工作时应考虑本机Azure Queue服务。您可以轻松扩展到多个队列使用者,而不必担心并发或特殊的负载平衡代码 - 只需增加(或减少)实例计数。

有关Windows Azure队列的更多信息,请查看Azure Platform Training Kit - 有几个简单的实验室可引导您完成队列基础知识。

答案 3 :(得分:0)

我想到的一点是,在使用队列时,重要的一点是订单会被保存,一旦它在队列中就会发生,它不会丢失。

现在pollers进程可能会死,他们有很多不同的问题,你不关心,队列是订单安全的地方。

轮询器不需要相同级别的稳健性。例如, Postfix 是邮件传输器的一种非常安全的实现,其中消息队列在很多级别中使用(应用程序中的每个子系统需要不同的安全级别与队列中的其他人进行通信) - 并且您可以关闭电源你不会丢失任何邮件,工人可以死得很厉害,邮件不能。

修改

这意味着基本用法是存储订单,忽略工人将使用的工具,有多少工人还活着等等。因此,处理多个队列的唯一原因是为您的订单管理多个目的地(应用程序)逻辑)而不是管理工人应该与他们合作的方式(解耦)。