【问题标题】:Synchronize access of queue workers同步队列工作者的访问
【发布时间】:2013-03-01 09:42:16
【问题描述】:

我目前正在编写一个使用 Steam Web API 抓取 DotA 2 比赛的服务。因为我希望我的解决方案具有可扩展性,所以我希望允许同时缓冲和处理爬网作业。这就是为什么想到队列的原因:

所有组件都应该能够在不同的计算机/VM 上运行(没有内存或进程间同步)。抓取作业可能是这样的:

Job 1: Crawl match 1234 with options ABC
Job 2: Crawl match 2345 with options BCD

由于数据的性质,指向同一个比赛的多个作业可能会被排入队列(例如,两个玩家玩同一个游戏)。因此,我需要一些队列无法提供的同步机制(爬虫不得尝试同时写入相同匹配的数据)。

我的实际问题是:是否有一种模式可用于同步需要访问相同数据的队列工作人员?

我想到的一种方法是引入另一种服务,允许爬虫进行Lock 匹配(这需要在从数据库读取或写入匹配数据之前完成):

但这会引入一大堆新问题和要求:

  • 如何缩放控制器?
  • 如果控制器崩溃怎么办?
  • 如果队列工作者没有解锁匹配怎么办?
  • ...

如果感兴趣,以下是我可能会使用的技术:

  • 队列:Windows Server 的服务总线
  • 服务:.NET Web API
  • 数据库:SQL Server 2012

【问题讨论】:

    标签: architecture synchronization queue web-crawler servicebus


    【解决方案1】:

    这听起来像是一个预订系统,是在线订票系统存在的那种问题 -

    user asks for tickets
    system offers specific tickets
    user thinks a while and maybe pays, during that think time system cannot offer tickets to anyone else
    eventually user buys, rejects or maybe just times out
    system updates ticket availability
    

    问题:在您的系统中,如果两个具有相同参数的爬虫同时搜索,并且它们不能同时更新结果,是否会出现问题? 我问的原因是我认为爬行动作本身类似于用户思考时间,这是一个长时间运行的动作,其持续时间持有数据库是不合理的 锁。

    我建议的方案是 乐观锁定,由数据库和数据库事务调解,因此不需要单独的控制器 - 您的数据库是单点故障,最终是可伸缩性瓶颈,但您可以通过对数据库进行一些分区来解决这个问题。

    您需要某种控制器。但它不必是单例。再次通过数据库锁调解实例。我看到的最大问题是可靠地捕获失败的爬虫。在“蓝天”场景中维护运行爬虫的数据库表很容易。失败案例在我看来非常棘手。

    我想知道诀窍是否是对数据库进行分区,每个分区对应一个具有自己控制器的“工作组”。只要控制器处于活动状态,它就可以启动工作并监管查询,以便在其工作组中不会出现重复。在任何爬虫完成后,一条“就绪”消息将排队,结果整合服务将数据从分区拉入主节点。

    【讨论】:

    • 如果两个爬虫都将相同的数据发布到数据库中,那么使用乐观锁定不会有问题。根据爬取作业的选项,爬虫可能需要等待其他爬虫将数据写入数据库,然后更改一些属性(因此INSERT 变为UPDATE) .这是由 Steam API 的工作方式造成的,我不能碰巧。
    • 我认为您没有提到您受到特定产品 API 的限制。如果这不能改变,我看不到一个简单的方法来处理这个问题。问题是要区分慢爬虫和死爬虫。
    • 非常感谢您对分区的提示。这使我想到我可以轻松实现一种算法,以确保某个匹配的作业将始终由同一个爬虫处理。这将完全消除同步/锁定问题。正如您所提到的,爬虫崩溃或挂起的问题仍然存在,但我认为服务总线可以解决这个问题。
    【解决方案2】:

    如果您需要关联队列中的一组/一组消息,您可以使用会话。此外,使用具有多个订阅的单个主题可能是基于订阅上设置的不同过滤器来划分消息的好方法。以下信息可能会有所帮助:

    1. (来自我的博客)http://abhishekrlal.wordpress.com/2012/02/07/enterprise-integration-patterns-with-service-bus-part-1/
    2. http://code.msdn.microsoft.com/windowsazure/Brokered-Messaging-Session-41c43fb4

    您可能需要将上述示例中的引用更新到 Azure SDK 1.8,因为它支持 Windows Server 的 Service Bus 1.0。

    【讨论】:

      猜你喜欢
      • 2018-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多