c# - Azure - C# 并发 - 最佳实践

标签 c# azure concurrency parallel-processing

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

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

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

思考这个问题的另一种方法是:如何使用 Azure 进行 Web 抓取 - 并确保不会使其运行的 VM 过载(就内存 + 网络而言)? (我认为在这种情况下你不需要太多的CPU处理)。

到目前为止我们已经尝试过:

  1. 使用的服务总线队列/工作角色扩展到 8 个小型虚拟机 - 但这会导致发生大量网络错误(每个工作角色虚拟机可以处理的数量必须存在一些网络限制) .
  2. 使用服务总线队列/连续 Web 作业扩展到 8 个小型虚拟机 - 但这似乎工作速度较慢 - 即使扩展,也无法让我们对幕后发生的情况有太多控制。 (我们真的不知道有多少虚拟机已启动)。

这些东西似乎是为 CPU 计算而构建的,而不是为 Web/API 抓取而构建的。

澄清一下:我将请求放入队列中,然后由我的多个虚拟机拾取该队列进行处理以获得响应。这就是我使用队列的方式。每个虚拟机都使用 Microsoft 规定的 ServiceBusTrigger 类。

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

最佳答案

实际上,我已经在 Azure 中启动并运行了网络爬虫一段时间了:-)

据我所知,没有“ Elixir ”。在截止日期前抓取大量资源非常困难。

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

  • 我使用辅助角色和 C# 代码作为代码本身。
  • 对于调度,我使用队列存储。我将爬行任务放入队列中并设置超时(例如“何时爬行”),然后让爬虫将它们拉下来。您可以在队列大小上设置触发器,以确保您在速度方面满足截止日期 - 我个人不需要它们。
  • SQL Azure 很慢,所以我不使用它。相反,我只使用表存储来存储抓取的项目。请注意,更新数据可能非常复杂。
  • 不要使用太多线程;相反,对所有网络流量使用异步 IO。
  • 此外,您可能还必须考虑额外的线程需要额外的内存(解析树可能会变得相当大) - 因此需要进行权衡...我确实记得使用了一些线程,但实际上只是少数。<

请注意,如果您现在使用线程方法,这可能确实需要您重新设计和重新实现完整的网络抓取工具。话又说回来,有一些好处:

  • 表存储和队列存储很便宜。
  • 我目前使用单个 Extra Small VM 来抓取一千多个网络资源。
  • 入站网络流量免费。
  • 因此,结果也相当便宜;我确信它比其他选择要少得多。

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

附注:这不仅适用于 Azure;也适用于 Azure。其中大部分也适用于本地抓取工具。

关于c# - Azure - C# 并发 - 最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32355154/

相关文章:

c# - "MaxAutoRenewDuration"在azure服务总线中的作用是什么?

.net - 这似乎是并发集合/队列组合的合理方法吗?

java - 从 ScheduledExecutorService 中提取异常

c# - 如何阻止 C# 程序循环自动存储上次 session 的输入?

c# - 如何并行运行一组函数并等待完成后的结果?

c# - DocuSign 连接 Webhook 与 .Net Core 3

c# - 使用 c# 的 Active Directory 属性列表

javascript - Azure 聊天机器人 token 服务器

Azure 媒体服务/播放器自动启动直播事件

Java 执行器 : Submitting a batch of tasks?