【发布时间】:2015-05-09 22:37:09
【问题描述】:
假设有一个工作服务从队列接收消息,从文档数据库中读取具有指定 Id 的产品,根据消息应用一些操作逻辑,最后将更新后的产品写回数据库 (a) .
当处理不同的产品时,这项工作可以安全地并行完成,因此我们可以水平扩展 (b)。但是,如果多个服务实例在同一个产品上工作,我们最终可能会遇到并发问题,或者数据库中的并发异常,在这种情况下,我们应该应用一些重试逻辑(但重试仍然可能再次失败等等) .
问题:我们如何避免这种情况?有没有办法确保两个实例不在同一个产品上运行?
示例/用例:一家在线商店在产品 A、产品 B 和产品 C 上进行了一次大促销,在一个小时内结束,数百名客户正在购买。对于每次购买,都会将一条消息排入队列(productId、numberOfItems、price)。 目标:我们如何运行我们的工作服务的三个实例,并确保 productA 的所有消息都将在 instanceA、productB 到 instanceB 和 productC 到 instanceC 中结束(不会导致并发问题)?
注意事项:我的服务是用 C# 编写的,作为辅助角色托管在 Azure 上,我使用 Azure Queues 进行消息传递,并且我正在考虑使用 Mongo 进行存储。此外,实体 ID 为 GUID。
更多的是关于技术/设计,所以如果您使用不同的工具来解决问题,我仍然感兴趣。
【问题讨论】:
-
+1 @GregD 的回答“了解您的数据模型和使用模式”,尽管我会更进一步。要消除并发性,您需要重新设计数据模型和业务逻辑,这样您就不会真正更新数据,而只是追加数据。仅追加数据模型是并发友好的 - 这意味着它们不会阻塞,但您可能需要重新设计从数据模型读取的逻辑。
-
@UdiDahan Append-only 模型听起来确实适合这里的问题,因此非常感谢您提供一些细节的答案
标签: azure scalability sharding microservices horizontal-scaling