解决Scrapy性能问题——案例二(含有阻塞的代码)
2016-04-26 16:11
239 查看
症状:系统非常慢,与期望的相差很大,并且当你修改
示例:你可以使用这两个设置项(爬虫代码见这里):
讨论:只要有阻塞的代码,那么Scrapy的并发性就毫无作用了,相当于设置了
,大概就是13s了,这样就能解释为什么会出现上面的情况了。
不管阻塞的代码是在pipeline中还是在爬虫中,你都会看到scraper被占满了,并且在它之前或者之后的组件都是空的。这似乎和之前讲过的pipeline的特点有些不符,但是现在已经并不是一个并发的系统了,所以之前的规则已经不适用了。我们很容易就会犯这样的错误,例如使用了阻塞的API,这样在运行的过程中一定会出现这种情况。同时也要注意不要写计算过于复杂的代码,对于这些代码应该使用多线程来处理,或者在Scrapy外进行批处理。
解决方法:如果整个系统不用添加任何pipeline就能运行,那么就先禁用所有的pipeline然后再检查这种情况是不是还在。如果还是这样,那么阻塞的代码就在爬虫中,如果这种情况不见了,那么阻塞的代码就在pipeline中。然后再一个一个地禁用pipeline并且观察什么时候问题以重新出现了。但是如果整个系统不能在没有任何一个组件的时候运行起来,那么可以在每个pipeline中加上日志信息并打上时间戳,通过检查日志就能发现你的系统在哪花费的时间最多。如果需要一种可重用性比较强的方法,那么可以在系统中加上一些没有实际功能的pipeline来跟踪
CONCURRENT_REQUESTS的值的时候,速度并没有发生变化。下载器看起来几乎是空的(比
CONCURRENT_REQUESTS的值要小),scraper中只有少量一些
Response对象。
示例:你可以使用这两个设置项(爬虫代码见这里):
SPEED_SPIDER_BLOCKING_DELAY和
SPEED_PIPELINE_BLOCKING_DELAY来使得对于每个响应都会有一个100ms的阻塞延迟。我们希望对于100个URL花费2-3s来完成,然而不管如何设置
CONCURRENT_REQUESTS的值,结果都是花费了13s左右。
for concurrent in 16 32 64; do time scrapy crawl speed -s SPEED_TOTAL_ITEMS=100 \ -s CONCURRENT_REQUESTS=$concurrent -s SPEED_SPIDER_BLOCKING_DELAY=0.1 done
讨论:只要有阻塞的代码,那么Scrapy的并发性就毫无作用了,相当于设置了
CONCURRENT_REQUESTS= 1。100个URL * 100ms(阻塞的延迟)= 10s +
,大概就是13s了,这样就能解释为什么会出现上面的情况了。
不管阻塞的代码是在pipeline中还是在爬虫中,你都会看到scraper被占满了,并且在它之前或者之后的组件都是空的。这似乎和之前讲过的pipeline的特点有些不符,但是现在已经并不是一个并发的系统了,所以之前的规则已经不适用了。我们很容易就会犯这样的错误,例如使用了阻塞的API,这样在运行的过程中一定会出现这种情况。同时也要注意不要写计算过于复杂的代码,对于这些代码应该使用多线程来处理,或者在Scrapy外进行批处理。
解决方法:如果整个系统不用添加任何pipeline就能运行,那么就先禁用所有的pipeline然后再检查这种情况是不是还在。如果还是这样,那么阻塞的代码就在爬虫中,如果这种情况不见了,那么阻塞的代码就在pipeline中。然后再一个一个地禁用pipeline并且观察什么时候问题以重新出现了。但是如果整个系统不能在没有任何一个组件的时候运行起来,那么可以在每个pipeline中加上日志信息并打上时间戳,通过检查日志就能发现你的系统在哪花费的时间最多。如果需要一种可重用性比较强的方法,那么可以在系统中加上一些没有实际功能的pipeline来跟踪
Request对象的处理过程,这些pipeline唯一的功能就是添加时间戳,最后再关联一下
item_scraped信号,把时间戳记录到日志中。在发现了阻塞代码的位置之后,把它替换成Twisted/异步的代码,或者使用Twisted的线程池。要试一下这种转换的效果,可以把
SPEED_PIPELINE_BLOCKING_DELAY替换成
SPEED_PIPELINE_ASYNC_DELAY再运行一下示例,就能发现性能的改变是惊人的。
相关文章推荐
- Java String.split()用法小结
- Yandex.Algorithm 2011 Round 2 D. Powerful array(莫队算法)
- c++对内存的浅谈以及内存泄漏问题的探讨之九
- php正则提取html图片(img)src地址与任意属性
- c++对内存的浅谈以及内存泄漏问题的探讨之八
- ASP.net 实现禁止用户重复登录
- C#中 Thread.Sleep精度问题
- spring注解方式实现DI和IOC
- c++对内存的浅谈以及内存泄漏问题的探讨之七
- C语言中内存对齐详解
- Spring AOP 常用的四种实现方式
- eclipse.ini 优化
- c++对内存的浅谈以及内存泄漏问题的探讨之六
- findBugs 代码静态扫描 学习笔记
- SpringMVC系列之主要组件
- C++关键词 —— mutable
- eclipse: workspace出错导致无法启用的解决
- c++对内存的浅谈以及内存泄漏问题的探讨之五(2)
- java实现定时任务(Quartz)
- java实现定时任务(Quartz)