解决Scrapy性能问题——案例四(响应太多导致溢出)

来源:互联网 发布:mac 字体 安装 位置 编辑:程序博客网 时间:2024/05/16 12:15

症状:下载器几乎是在满负荷工作,然后过一会就关闭了。然后一直重复这样,而scaper占用的内存很多。

示例:这里我们和之前的设置是一样的(也使用了treq),但是响应的大小被设置成了120kb的HTML。正如你所看到的,它一共花费了31s而不是20s:

$ time scrapy crawl speed -s SPEED_TOTAL_ITEMS=1000 -sSPEED_T_RESPONSE=0.25 -s SPEED_API_T_RESPONSE=1 -sSPEED_PIPELINE_API_VIA_TREQ=1 -s SPEED_DETAIL_EXTRA_SIZE=120000s/edule d/load scrape p/line done mem952 16 32 32 0 3842818917 16 35 35 32 4203080876 16 41 41 67 4923608840 4 48 43 108 5764224805 3 46 27 149 5524048...real 0m30.611s

讨论:我们可能简单地把这些延迟为花费了更多的时间来创建、转移或者处理网页。但是实际上并不是这样,对于所有Response对象的总的大小在写本书的时候有一个硬性的限制max_active_size = 5000000。每个Response对象被假定它们的大小与它里面的HTML代码大小相等,并且最小是1kb。

这里写图片描述

这里一个非常重要的细节是,这个限制或者是Scrapy用以保证爬虫和pipeline运行速度的最微妙最必要的机制。如果你的任何一个pipeline的吞吐量小于下载器的吞吐量,那么这种现象就最终会发生。当pipeline处理时间比较长的时候,即使是小的Response对象也会导致突破限制值。

解决方案:基于现有的框架基础,我们能做的事情不多。所有能做的就是减少pipeline的处理时间以减少scraper中的Response对象的数目。对此可以使用传统的优化方法:检查你与之交互的web api或者数据库能否支撑你的scraper的吞吐量,把scraper的功能简单化,以及把一些复杂的功能从pipeline中移到批处理/后处理系统中,或者使用性能更好的服务器或分布式地抓取。

0 0
原创粉丝点击