Azure - C#并发 - 最佳实践

时间:2015-09-02 13:54:46

标签: c# azure concurrency parallel-processing

我们正在使用Microsoft Azure抓取基于Web的API。问题在于需要检索大量数据(涉及组合/排列)。

如果我们使用标准的Web Job方法,我们计算出处理我们想要得到的所有数据大约需要200年 - 我们希望我们的数据每周刷新一次。

来自API的每个请求/响应大约需要0.5-1.0秒来处理。请求大小平均为20000字节,平均响应为35000字节。我相信请求的总数是数百万。

另一种思考这个问题的方法是:你将如何使用Azure进行网络搜索 - 并确保你不会超载(就内存+网络而言)它的虚拟机跑? (在这种情况下,我认为你不需要太多CPU处理。)

到目前为止我们尝试过:

  1. 使用服务总线队列/工作者角色扩展到8个小型虚拟机 - 但这会导致很多网络错误发生(必须对EACH工作者角色VM可以处理的数量有一些网络限制)
  2. 使用服务总线队列/连续Web作业扩展到8个小型虚拟机 - 但这似乎工作得更慢 - 甚至是缩放,并没有让我们过多地控制什么'在幕后发生的事情。 (我们真的不知道有多少虚拟机在运行)。
  3. 似乎这些内容是为CPU计算而构建的 - 而不是用于Web / API抓取。

    只是为了澄清:我将我的请求放入一个队列 - 然后由我的多个VM接收,以便进行处理以获得响应。这就是我如何使用队列。每个VM都使用了microsoft规定的ServiceBusTrigger类。

    1. 拥有大量小型虚拟机或少量大型虚拟机会更好吗?
    2. 我们应该关注哪些C#类?
    3. 尝试在Azure上执行此类操作时有哪些技术最佳做法?

2 个答案:

答案 0 :(得分:2)

我有一些刮刮经验,所以我会分享我的想法。

  1. 似乎这些内容是为CPU计算而构建的 - 而不是用于Web / API抓取。
  2. 它们是为动态扩展而构建的,因为您的任务不是您真正需要的。

    1. 如何确保您不会使VM过载?
    2. 测量响应时间和错误率并调整代码以降低它们。

      1. 在这种情况下,我认为您不需要太多的CPU处理。
      2. 取决于每秒传入多少数据以及您正在使用它做什么。对快速传入的数据进行更复杂的解析(如果您决定在同一台机器上执行此操作)将很快耗尽CPU。

        1. 8个小型虚拟机导致发生大量网络错误(必须有一些网络限制)
        2. 虚拟机越小,共享资源越少。存在吞吐量限制,然后您的邻居与您共享实际硬件存在问题。通常,实例大小越小,遇到的麻烦就越多。

          1. 拥有大量小型虚拟机或少量大型虚拟机会更好吗?
          2. 根据我的经验,较小的虚拟机太瘫痪了。但是,您的里程可能会有所不同,这完全取决于特定任务及其解决方案的实施。真的,你必须在自己的环境中衡量自己。

            1. 我们应该关注哪些C#课程?
            2. 尝试在Azure上执行此类操作时有哪些技术最佳做法?
            3. 通过高吞吐量抓取,你应该关注基础设施。您将在不同的Azure数据中心中拥有不同的延迟,以及不同VM大小的网络延迟/持续吞吐量的不同体验,具体取决于与您共享硬件的人员。最佳做法是尝试找到最适合您的方法 - 更改数据中心,VM大小和其他实验。

              Azure可能不是解决此问题的最佳解决方案(除非您正在消费狂欢)。 8个小型虚拟机每月450美元。这足以支付具有256Gb RAM,40个硬件线程和500Mbps - 1Gbps(甚至高达几Gbps突发)质量网络带宽的无托管专用服务器,而不会出现延迟问题。

              对于您的预算,您将拥有一个无法超载的专用服务器。您将拥有足够的RAM来处理异步固定(如果您决定进行异步),或者有足够的硬件线程用于多线程同步IO,从而提供最佳吞吐量(如果您选择与固定大小的线程池同步)

              在旁注中,根据API的具体情况,当您开始对API端点施加过大压力时,可能会发现主要问题是API所有者只是将您限制为爬行。

答案 1 :(得分:2)

实际上,在Azure中,我已经启动并运行了一个web scraper,已经有一段时间了: - )

AFAIK没有“魔弹”。用截止日期刮掉很多来源是相当困难的。

它如何运作(最重要的事情):

  • 我使用工作角色和C#代码来代码本身。
  • 为了安排,我使用队列存储。我将爬行任务放在队列上并超时(例如'何时爬行')并让刮刀将它们拉下来。您可以在队列大小上设置触发器,以确保您在速度方面达到最后期限 - 我个人并不需要它们。
  • SQL Azure很慢,所以我不使用它。相反,我只使用表存储来存储已删除的项目。请注意,更新数据可能非常复杂。
  • 不要使用过多的线程;相反,对所有网络流量使用异步IO。
  • 另外你可能不得不考虑额外的线程需要额外的内存(解析树可能会变得很大) - 所以那里有一个权衡...我记得使用一些线程,但它只是一些。

请注意,如果您现在使用线程方法,这可能需要您重新设计并重新实现完整的Web scraper ..然后,还有一些好处:

  • 表存储和队列存储很便宜。
  • 我目前使用一个额外的小型虚拟机来抓取超过一千个网络资源。
  • 入站网络流量是免费的。
  • 因此,结果也很便宜;我敢肯定它比替代品少得多。

至于我使用的类......好吧,这是一个很长的列表。我正在使用HttpWebRequest来处理异步HTTP请求和Azure SDK - 但其余的都是手工制作的(而不是开源的)。

P.S。:这不仅适用于Azure;其中大部分也适用于内部部署的刮刀。