4

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

我需要保留/存档存储表后处理中的所有事务,因此我可以使用一组表用于队列,并在处理它们时将它们移动到存档表中,或者也许有一种方法可以在一张桌子上做这个,不确定。

对于在我的工作角色中分配这些队列中的当前工作负载的机制,您有什么建议?显然,每个角色都必须知道其他角色在做什么,所以他们只处理无人认领的交易。我认为每个角色将从队列中检索 1000 条记录作为单个工作负载,并且多个工作角色可能在同一个队列上工作。

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

非常感谢您的建议。

4

4 回答 4

9

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

例如:

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

笔记:

  1. 使用队列服务(来自存储)或服务总线队列。
  2. 在多个队列之间分散负载以实现可扩展性。
  3. 确保在所有级别应用适当的处理来解决瞬时故障。
  4. 处理多次处理同一消息的可能性(处理应该是幂等的)。
于 2013-02-20T00:39:20.380 回答
1

我同意费尔南多的观点。请看一下我关于这个主题的博客文章;它与 Azure 队列的大规模处理有关。这是基于我所做的一个项目,其吞吐量要求比您发布的更高。

于 2013-02-20T00:52:13.993 回答
1

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

于 2013-02-20T01:58:02.850 回答
1

您可能需要考虑以下基于 CQRS 的松散方法。

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

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

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

为了在工作角色端获得更高的吞吐量,可以并行提取和处理消息。Azure 队列保证一次仅由一个客户端检索一条消息(除非可见性超时)。您可以支持幂等性,假设该消息可能已部分或全部更早地处理。

于 2013-02-20T07:09:55.713 回答