解决Scrapy性能问题——案例五(Item并发太多导致溢出)

症状:爬虫对于每个Response都产生了多个Item,系统的吞吐量比期望的要低,并且可能会出现和前一个案例相同的下载器开/关现象。

示例:这里我们假设有1000个请求,每个返回的页面有100个Item,响应时间为0.25s,Item在pipeline中的处理时间为3s。分别把CONCURRENT_ITEMS设置成从10到150的值来运行爬虫:

for concurrent_items in 10 20 50 100 150; do
time scrapy crawl speed -s SPEED_TOTAL_ITEMS=100000 -s
SPEED_T_RESPONSE=0.25 -s SPEED_ITEMS_PER_DETAIL=100 -s
SPEED_PIPELINE_ASYNC_DELAY=3 -s
CONCURRENT_ITEMS=$concurrent_items
done

结果如下:

s/edule d/load scrape p/line done mem
952 16 32 180 0 243714
920 16 64 640 0 487426
888 16 96 960 0 731138

在这里插入图片描述

讨论:需要再次提醒一下的是,这只适于用你的爬虫对每个响应都会产生很多Item的情况。如果不是这种情况,把CONCURRENT_ITEMS设置成1就相当于这种情况了。

第一个注意到的是,p/line列的数值和scape列的数值存在着某种关系,p/line = CONCURRENT_ITEMS · scape,这种我们所期望的一样,因为scape表示的是Response的数目而p/line表示的是Item的数目。

第二个有趣的事是图11中的性能曲线,虽然图的纵轴已经经过了缩放,以便更好地展示不同设置之间的差别,但是实际上差别并没有那么大。从图上可以看出,在坐标轴左侧的延迟很高,因为Item不能及时地处理导致Response对象积压以致于达到了内存的限制(前一个案例讲过);而在坐标轴的右边是因为并发的数目太多,使用了太多的CPU。不过把性能正好高估在某个最优点上也不是那么重要,因为在实际使用中,很容易地就往左或者往右偏移了一点。

解决方法:如果CPU的使用率很高,那就减小CONCURRENT_ITEMS的值;如果达到了Response对象的5MB的内存限制,说明你的pipeline的吞吐量跟不上下载器的吞吐量了,那就增加CONCURRENT_ITEMS的值,以加快处理Response的速度。如果设置这个CONCURRENT_ITEMS的值还是没有作用,那就看一下前一个案例中的建议,并仔细地分析一下你的scraper的吞吐量是否能被其余的系统所支撑。

猜你喜欢

转载自blog.csdn.net/weixin_40976261/article/details/89034314
今日推荐