使用Azure存储表作为具有多个工作者角色的队列进行处理吗?

时间:2013-02-20 00:03:19

标签: architecture azure azure-storage

我的应用程序将通过Web角色的多个实例每秒接收1000多个请求/事务。这些角色将为多个存储表中的每个事务写入一条记录(随机,以传播Azure的500个事务/秒限制)。现在,我需要一种可靠的方法来使用多个Worker Roles处理/聚合这些数据,并将结果写入我的SQL数据库。 AKA,这需要横向扩展。

我需要保留/存档存储表后处理中的所有事务,因此我可以使用一组表用于队列,并在处理它们时将它们移动到存档表中,或者可能存在一种在单个表上执行此操作的方法,不确定。

对于在我的工作角色中分配这些队列中的当前工作负载的机制,您会建议什么?显然,每个角色都必须了解每个其他角色的工作原理,因此它们只能处理无人认领的事务。我认为每个角色将从队列中检索1000条记录,因为单个工作负载和多个工作者角色可能在同一个队列上工作。

我是否应该将工作者角色“状态”保留在缓存中,可能在SQL服务器中。

非常感谢您的建议。

4 个答案:

答案 0 :(得分:7)

我建议您使用正确的队列服务来实现此功能,而不是尝试通过表服务实现排队。这样,您就不必实现复杂的逻辑来了解哪些记录已被处理(当您考虑容错和可能的错误时,逻辑变得困难,尤其是在具有非常有限的事务能力的表存储等服务中)。尝试可靠地协调多个工作人员,考虑所有可能的故障情况,并同时进行可扩展,这是我不会在应用程序级别尝试的。

例如:

  1. Web角色收到代表交易的请求;
  2. Web角色将数据写入多个表;
  3. Web角色向表示具有某个唯一ID的事务的队列服务发送消息(例如,如果没有其他合适的主键,则为请求ID)。
  4. 辅助角色从队列中提取消息。
  5. 对于每条消息,worker角色从表存储中检索对应于消息唯一标识符的对象集。
  6. worker角色根据需要聚合数据并将其写入SQL数据库。
  7. 注意:

    1. 使用队列服务(来自存储)或服务总线队列。
    2. 在多个队列之间传播负载以实现可伸缩性。
    3. 请务必在各个级别采取适当的处理措施,以应对瞬时故障。
    4. 处理多次处理同一消息的可能性(处理应该是幂等的)。

答案 1 :(得分:1)

我同意费尔南多的观点。请关注这个主题my blog post;它与Azure队列的大规模处理有关。这是基于我所做的项目,其吞吐量要求高于您发布的项目。

答案 2 :(得分:1)

我同意费尔南多的观点。队列服务API中的GetMessages方法允许在单个事务中对指定数量的消息进行排队。如果正确实现出队逻辑,您可能不必担心处理是幂等的,但它会使您的解决方案更加健壮。

答案 3 :(得分:1)

您可能希望在CQRS上松散地考虑以下方法。

Web角色验证事务并将其写入一个或多个队列。 (如果遇到队列限制,您可能需要以随机或循环方式写入多个队列。) 请注意,队列只是一个管道或管道,用于将Web角色与工作者角色分离,并且消息的格式并不重要。我会尝试将事务建模为对象并将其序列化以获取队列消息。如果转换太大而无法写为队列消息,则可以写入表或blob存储并在队列消息中引用该资源。

工作者角色,轮询一个或多个队列(随机或以循环方式)并处理事务,根据需要写入SQL和/或表存储。

这种架构的合理性允许独立扩展Web和工作者角色,并减少它们之间的依赖关系。 Web角色只需知道如何验证和序列化事务,而不知道如何持久化或处理事务。

对于辅助角色端的更高吞吐量,可以并行提取和处理消息。 Azure队列保证一次只能由一个客户端检索单个消息(除非可见性超时)。您可以通过假设消息可以部分或完全早期处理来支持幂等性。