作者 | Nariman Jelveh@Mixnode Technologies Inc. 译者 | 弯月 责编 | 郭芮 出品 | CSDN(ID:CSDNnews) 以下为译文: 我们公司Mixnode的背后由一个极其高效的分布式网络爬虫驱动,每秒可以访问几十万个网页。虽然在使用Mixnode时,你从来不需要考虑有关网络抓取的东西,但还是有很多人询问我们如何才能如此快速地抓取这么多网页。 在这篇文章中,我将与大家分享多年来我们在构建与优化爬虫方面所获得的经验以及教训。 Java 在为项目选择编程语言时,许多因素都会影响到你的最终决策。内部专业知识、生态系统和原始性能是我们在寻找“完美”的编程语言时必须考虑的主要标准。 最终,我们认为Java是我们的最佳选择,原因如下:
虽然我们的核心网络爬虫引擎是用Java编写的,但在为手头的工作选择编程语言时我们都很务实。例如,我们也使用其他语言(例如Python,Perl和Node.js)来编写脚本、配置、监视、报告和管道的其他部分。 无共享架构 在Mixnode,我们的集群采用了无共享架构,工作负载在独立的无状态节点上进行分割和分布,这可以消除大规模分布式系统的灾难——单点故障。另外,该架构允许我们逐个节点更新和升级底层软件,而不会中断整个操作。 此外,无共享架构大大减少了节点之间的通信开销,从而为我们提供了额外的性能提升。 速率限制模块必须保证安全 网站的主要设计目的是供人类访问,一位普通用户每分钟只能浏览很少的页面。网络爬虫每秒能够访问数千甚至数百万个网页,因此,如果不小心,网络爬虫很容易在很短的时间内耗尽网站资源,造成破坏性的后果。而且,一个普通的网站会有多个机器人同时抓取,所以这个问题会被放大。 因此,每个网络爬虫也有责任对自己的请求速率进行限制,换句话说,确保连续两次访问之间有适当的延迟。你需要对请求速率进行限制的三个最重要的标准是:主机名和IP地址。 很显然,这项工作需要从一开始就做到尽善尽美。由于一个简单的错误就可能对你正在抓取的网站造成破坏性的后果,所以不容许出错。在多线程环境中,在跟踪请求和速率限制参数时,你还应该格外小心以防止竞争。 缓存是王道 在构建大规模数据驱动的应用程序时,缓存网络事务通常是不可避免的,至少在管道的某些部分如此,特别是当相较于其他任务网络输入/输出更频繁且开销更大的情况下。但是,在大规模网络爬取的情况下,缓存不仅是不可避免的,而且是在编写代码之前就需要考虑的事项。 大规模网络爬取的情况下,有两个操作需要及时缓存:
解析HTML 爬虫的基本任务之一就是从它访问的每个页面中提取链接(即解析),以便将它们添加到需要访问页面的队列中。如果你需要大规模的爬取,那么最好有一个高性能的HTML解析器,因为你需要提取大量的链接和元数据。 大多数HTML解析库会优先考虑简单性、易用性和通用性,一般来讲这是正确的设计。由于我们需要高速的链接提取,所以最终我们决定编写自己的解析器,并针对查找链接和一些原始DOM的查询功能进行了优化。 HTML解析器还需要具有弹性,经过全面的测试,并且能够处理大量出现的异常情况,因为并非每个HTML文档都是有效的。 网络优化 通常操作系统的默认配置无法处理大规模网络爬虫的网络需求。通常我们需要根据具体情况,优化操作系统的网络堆栈,使其发挥最大潜力。对于大规模的网络爬虫来说,优化的目标在于最大化吞吐量和打开连接的数量。 以下是我们经常会用到的有关该主题的一些有用的资源:
小结 构建大规模网络爬虫是一项长期的项目,也是一项复杂的工作。我们必须精心设计和测试不同的模块,同时还需仔细观测和研究权衡利弊。许多我们日常使用的计算机软件组件都无法在网络爬虫的工作负载下正常运行,因此我们需要从头开始设计,同时还需不断审查和优化其他组件,才能适应不断变化的不断扩大的网络。 我们的网络级爬虫经过了漫长的发展,才成为了成熟稳定的平台,我们期待分享更多关于学习构建基础架构的经验教训。
|
|