在多个实例中控制azure worker角色并发

时间:2011-01-13 18:07:53

标签: azure azure-sql-database azure-worker-roles

我在azure中有一个简单的工作角色,可以在SQL azure数据库上进行一些数据处理。 工作人员基本上每2分钟将数据从第三方数据源添加到我的数据库。当我有两个角色实例时,这显然会不必要地加倍。我想有2个冗余实例和99.95正常运行时间,但不希望它们同时处理,因为它们只是复制相同的工作。我缺少一个标准模式吗? 我知道我可以在数据库中设置标志,但我希望有另一种更简单或更好的方法来管理它。 感谢

4 个答案:

答案 0 :(得分:7)

正如Mark建议的那样,您可以使用Azure队列发布消息。您可以让worker角色实例将后续消息发布到队列,作为处理当前消息时的最后一项操作。这应该处理马克提出的关于信号量需求的问题。在队列消息中,您可以在处理消息时嵌入时间戳标记。创建新消息时,只需将当前时间添加两分钟。

并且......如果不明显:如果工作者角色实例在完成处理之前崩溃并且无法重新发布新的队列消息,那就没问题了。在这种情况下,当前队列消息将简单地重新出现在队列中,然后另一个实例可以自由地处理它。

答案 1 :(得分:0)

没有一种超级简单的方法可以做到这一点,我不这么认为。

您可以使用Mark提到的信号量来基本记录处理的开始和停止。然后,您可以运行任意数量的实例,每个实例都检查信号量记录,并且只有在信号量允许的情况下才会执行。

但是,这里需要注意的是,如果其中一个实例在处理过程中崩溃并且从不释放信号量,会发生什么?您可以实现一个“超时”值,如果在X时间内没有解锁,其他实例将尝试启动处理。

或者,您可以使用第三方监控服务(如AzureWatch)来监视Azure中无响应的实例,并在“就绪”实例的数量低于1时启动新实例。这样可​​以节省一些通过不必一直启动和运行2个实例,但实例失败和启动新实例之间存在轻微的延迟。

答案 2 :(得分:0)

建议的Semaphor是可行的方法,虽然我可能会在blob商店中使用简单的时间戳心跳。

另一个想法是,它有多重要?如果您的负载可以持续几分钟,可能只是让角色回收?

答案 3 :(得分:0)

大卫解决方案的小问题。将消息重新发布到队列将作为当前执行的最后一件事发生,这样如果机器崩溃,当前消息将过期并重新浮出队列。这假定消息最初是偷看的,需要排队操作才能从队列中删除。在将新消息插入队列之前必须发生出队。如果角色在这两个操作之间崩溃,那么系统中将不会有任何令牌停止。 ESB重复检查听起来像是一种可行的方法,但由于总线只能检查当前存在于队列中的相同消息,因此它听起来并不确定。但是,如果其中一条消息在前一个消息出现后立即进入,则有可能最终并行运行2个进程。

另一种解决方案,如果你能负担得起,将永远不会排队并通过Peek操作租用消息。您必须确保隐身超时永远不会超出工作者角色的处理时间。就首先创建令牌而言,之前描述的相同工作者角色启动策略与ASB重复检查相结合应该有效(因为消息永远不会从队列中移出)。