0

我必须尽可能快地抓取数千个不同的网站。在单个节点进程上,我每秒能够获取 10 个 url。虽然如果我将任务分配给 10 个工作进程,我可以达到 64 个请求/秒。

为什么会这样?为什么我在单个进程上被限制为 10 个请求/秒,并且必须生成工作人员才能达到 64 个请求/秒?

  • 我没有达到最大套接字/主机(agent.maxSockets)限制:所有 url 都来自唯一主机。
  • 我没有达到最大文件描述符限制(AFAIK):我的 ulimit -n 是 2560,并且 lsof 显示我的抓取工具从不使用超过 20 个文件描述符。
  • 我在 sysctl.conf 中增加了 kern.maxfiles、kern.maxfilesperproc、kern.ipc.somaxconn 和 kern.ipc.maxsockets 的设置,然后重新启动。没有效果。
  • 尝试增加 ulimit -n。没变。

有什么我不知道的限制吗?我在 Mac OS-X 上。

4

1 回答 1

1

我不认为每秒有 10 个请求的硬性限制,这似乎是 node.js 能够在单个进程上爬行的最高速度。爬行的基本原理是这样的:

  1. 请求 HTML 页面。
  2. 解析 HTML 页面。
  3. 执行 JavaScript。
  4. 做一些后期处理。
  5. 加载下一个候选 URL。

在每秒 10 个请求的情况下,您在 1 秒内执行上述步骤 10 次。您的爬虫可以在单个进程(线程)上爬取的最快速度是带宽连接的速度,也就是说,如果您只执行第 1 步。如果您正在执行第 2 到第 5 步,那么您的爬取速度将是低于您的带宽连接,因为您在每个 Web 请求之间执行其他操作。

为了最大限度地提高速度,您必须确保不断执行第 1 步,直到最大限度地利用带宽连接,而要做到这一点的方法是添加更多进程(线程)。一个非常简单的例子是考虑这种情况:步骤 1 可以概括为Fetching,步骤 2 到 5 可以概括为Processing。因此,如果您有 2 个进程同时工作,一个可以在另一个正在处理的同时获取,理论上这将最大化您的吞吐量。实际上(正如您所发现的),您需要的不仅仅是两个过程,因为处理部分有多个步骤。

如果您认为平均网页约为 128 KB,那么当您使用单个进程每秒发出 10 个请求时,您的带宽使用量将为 10 Mbps。对于 64 个请求,您至少需要 64 Mbps 的带宽速度。那么您的带宽连接真的是 64 Mbps 吗?

于 2012-06-07T15:32:03.387 回答