下面这些是潜在的影响爬取效率的内容(官方资料翻译):
html
1)DNS设置
2)你的爬虫数量,太多或太少
3)带宽限制
4)每一主机的线程数
5)要抓取的urls的分配不均匀
6) robots.txt中的高爬取延时(一般和urls的分配不均匀同时出现)
7)有不少比较慢的网页(一般和分配不均匀同时出现)
8)要下载太多的内容(PDF,大的html页面,一般和分配不均匀同时出现)
9)其它java
那如今怎样改善它们?
node
1)在每个本地的爬虫机器上设置DNS,若是是多个爬取机器和一个单独的DNS中心这种状况,那么它就会像有DOS攻击在DNS服务器上那样,使整个系统变慢。咱们常常设置两层,首先命中本地DNS缓存,而后就是大的DNS缓存,就像OpenDNS或Verizon。
2)这将是map任务数乘以fetcher.threads.fetch属性值的数量。因此10个map任务*20个线程=一次200个爬取列表。太多的话会超过你系统的负担,太少的话就会使一些机器闲置。你须要认真考虑在你的环境下如何设置这些属性。
3)带宽限制,用ntop,ganglia和其它监控软件来测定你使用了多少的带宽。计算输入和输出的带宽。能够作一个简单的测试,用抓取网络中一台不用做爬虫的服务器中,若是它与其中一台爬虫机器链接时或当那台机器抓取时从中下载信息时很是慢,这时你就能够加大带宽。若是你像我后来讲的那样设置http的超时时间而且增长了你的带宽,你会开始看到不少http超时的错误。
4)urls分配的不均匀颇有多是限制性能的一个最大的因素。若是一个线程正在处理一个网站而且那个网站还有不少url等待抓取,那么其它线程就会闲置直到那个线程完成抓取。一些解决方法是,使用fetcher.server.delay来缩短网页抓取之间的时间间隔,和使用fetcher.threads.per.host来增长同一网站抓取的线程数(这仍然在同一个map任务中,所以也是在同一个JVM中的子任务中处理)。若是把这些属性都设置为大于0,你也能够设置fetcher.server.min.delay属性大于0来设置处理的最小和最大的界限。
5)在一个网站上抓取大量的网页或在少许网站上抓取大量的网页将显著地下降抓取的速度。对于全网爬取,你但愿用分布式环境来使全部抓取线程活动。设置generate.max.per.host大于0将限制在同一网站/域名抓取网页的数量
6)爬取延迟。大多数网站不使用这些设置只有少数使用(一些恶意的网站)。我见过爬取延迟每秒最长延迟2天的.fetcher.max.crawl.delay属性将忽略爬取延迟大于x的页面。我常常把它设置成10秒,默认是30秒。尽管设置为10秒,若是你在某个网站上有大量的页面要爬取,但你只能每10秒爬取一个页面,这样也是很慢的。另外一方面,把它的值设置太小将忽略该页面而且不抓取这些网页。
7)有时,网页恰好很慢。设置http.timeout一个低点的值就有助于这种状况。它的默认值为10秒。若是你不在乎并想全部网页都尽量的快,设置得小点。一些网站。例如digg,会在网站中限制你的带宽而且只容许在某个时间段内存在x个到你机器的链接。因此即便你只在一个网站中爬取50个网页(我仍然认为太多了)。这样将在每一页面中等待10秒。ftp.timeout也能够用来设置抓取ftp的内容时的时间间隔。
8)大量的内容意味着要下降抓取的速度。特别是下载PDF或其它非html的文件时。为了不下载非html的内容,你可使用url过滤器。我更喜欢prefix和suffix过滤器。http.content.limit和ftp.content.limit属性能够限制一个文档中下载数据的多少。
9)其它可能致使抓取变慢的因素:
一台机器最大可打开的socket或文件的多少。你可能会开始看到IO错误或不能打开socket的错误。低效的路由。坏的或家里的路由不能控制同一时间大量链接的创建。一个错误的路由设置也可能致使问题但这些问题一般很难发现。若是你认为是这个问题,能够用网络跟踪和映射工具来查找。反向的路由则多是你网络供应商的问题。坏的网卡。我曾经见过一些网卡忽然达到了某个带宽值。这个问题在使用新的网卡时更加广泛。这一般不是我首先想到的可是一般是可能会出现的。可使用tcpdump和网络监控apache
本次优化方向:缓存
A,1)3)为硬件,设置好了之后改变不大。暂不考虑。
B,5)generate.max.per.host暂设置为0。暂不考虑。
C,8)本次爬虫设置只爬取网页内容,不爬媒体文件。
D,2)4)6)7)9)为优化目标服务器
Hadoop配置:网络
三台:主机内存8G,2台slave内存20G,主从内存配置不合理有必定缘由,这里就再也不赘述。之后也是一个优化方向socket
网络带宽:100M
tcp
优化前的准备工做:分布式
没有优化以前,种子数量在10条左右的时候,单机版和Hadoop版的爬取效率大约都在2条/秒(包括创建索引)。
优化了Nutch索引,stored和indexed,索引不须要存储的尽可能不存储,不须要索引的尽可能不索引。而且去掉没必要要的索引项目。当种子数增长到40条左右的时候,Hadoop版的爬取效率大约在3.5条/秒。由此肯定了种子数量对爬取有影响的优化方向。
参照hadoop的优化方针,作了以下优化:
1,优化系统参数 readahead buffer
blockdev --report
blockdev --setra 1024 /dev/sda
2,优化hadoop参数
hdfs-default
dfs.namenode.handler.count:20
dfs.datanode.handler.count:5
dfs.replication:3
mapred-default.xml
mapreduce.tasktracker.http.threads:50
io.sort.factor:20
mapred.child.java.opts:-Xmx400m
mapreduce.task.io.sort.mb:200
mapreduce.map.sort.spill.percent:0.8
mapreduce.map.output.compress:true
mapreduce.map.output.compress.codec:org.apache.hadoop.io.compress.DefaultCodec com.hadoop.compression.lzo.LzoCodec为最优
mapreduce.reduce.shuffle.parallelcopies:10
优化开始:
2014/7/9 上午
优化内容:
增大种子数:选取的3000左右的有效的国外网站。
yarn-site
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>2048</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>3072</value>
</property>
mapred-site
<property>
<name>mapreduce.map.memory.mb</name>
<value>1536</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>2560</value>
</property>
<property>
<name>mapreduce.map.java.opts</name>
<value>-Xms512m -Xmx1024m</value>
</property>
<property>
<name>mapreduce.reduce.java.opts</name>
<value>-Xms1024m -Xmx2048m</value>
</property>
slave
yarn-site
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>3072</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>6144</value>
</property>
mapred-site
<property>
<name>mapreduce.map.memory.mb</name>
<value>4096</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>8192</value>
</property>
<property>
<name>mapreduce.map.java.opts</name>
<value>-Xms2048m -Xmx3072m</value>
</property>
<property>
<name>mapreduce.reduce.java.opts</name>
<value>-Xms5120m -Xmx6144m</value>
</property>
结果:
共爬取并创建了91986条solr索引,共耗时22235秒。最终效率:4.14条/秒。
4.136991 | ||||
2923 | 2923 | 11:06:05 | 11:20:51 | 0:14 |
36538 | 33615 | 11:20:51 | 13:13:38 | 1:52 |
68255 | 31717 | 13:13:38 | 15:16:42 | 2:03 |
91986 | 23731 | 15:16:42 | 17:16:40 | 1:59 |
2014/7/9 下午
优化内容:
nutch-site
<name>fetcher.threads.per.host</name> 5
<name>fetcher.threads.fetch</name>20
结果:
回 数 |
效率 | 5.38条/秒 | 全体 | Nutch | Index | |||||||||
总条数 | 每回条数 | 开始 | 终了 | 耗时 | 速度 | 开始 | 终了 | 耗时 | 速度 | 开始 | 终了 | 耗时 | 速度 | |
1 | 2923 | 2923 | 18:22:04 | 18:48:55 | 1611 | 1.81 | 18:22:04 | 18:35:13 | 789 | 3.70 | 18:37:05 | 18:48:55 | 710 | 4.12 |
2 | 36538 | 33615 | 18:49:41 | 20:59:04 | 7763 | 4.33 | 18:49:41 | 20:20:31 | 5450 | 6.17 | 20:22:18 | 20:59:04 | 2206 | 15.24 |
3 | 68255 | 31717 | 21:00:11 | 22:57:35 | 7044 | 4.50 | 21:00:11 | 22:26:21 | 5170 | 6.13 | 22:28:08 | 22:57:35 | 1767 | 17.95 |
4 | 91986 | 23731 | 22:59:19 | 0:58:52 | 7173 | 3.31 | 22:59:19 | 0:28:49 | 5370 | 4.42 | 0:31:03 | 0:58:52 | 1669 | 14.22 |
5 | 115646 | 23660 | 1:00:49 | 2:49:14 | 6505 | 3.64 | 1:00:49 | 2:19:21 | 4712 | 5.02 | 2:21:19 | 2:49:14 | 1675 | 14.13 |
结论:
速度从4.14-〉5.38,提高了29.95%。从这一点来看Nutch的fetch线程数目对爬取效率有必定影响。
2014/7/10
优化内容:
根据7/9日的方向,增长fetch线程数。
nutch-site
<property>
<name>fetcher.threads.fetch</name>
<value>100</value>
</property>
<property>
<name>plugin.includes</name>
<value>protocol-http|urlfilter-regex|parse-html|index-(basic|customized)|indexer-solr|scoring-opic|urlnormalizer-(pass|regex|basic)</value>
</property>
<property>
<name>indexer.skip.notmodified</name>
<value>true</value>
<description>Whether the indexer will skip records with a db_notmodified status.
</description>
</property>
结果:
回 数 |
效率 | 6.22条/秒 | 全体 | Nutch | Index | |||||||||
总条数 | 每回条数 | 开始 | 终了 | 耗时 | 速度 | 开始 | 终了 | 耗时 | 速度 | 开始 | 终了 | 耗时 | 速度 | |
1 | 3014 | 3014 | 15:01:01 | 15:26:07 | 1506 | 2.00 | 15:01:01 | 15:13:30 | 749 | 4.02 | 15:15:13 | 15:26:07 | 654 | 4.61 |
2 | 39069 | 36055 | 15:26:54 | 17:34:55 | 7681 | 4.69 | 15:26:54 | 17:01:35 | 5681 | 6.35 | 17:03:25 | 17:34:55 | 1890 | 19.08 |
3 | 73156 | 34087 | 17:35:57 | 19:33:36 | 7059 | 4.83 | 17:35:57 | 18:59:06 | 4989 | 6.83 | 19:01:08 | 19:33:36 | 1948 | 17.50 |
4 | 103994 | 30838 | 19:34:55 | 21:46:40 | 7905 | 3.90 | 19:34:55 | 21:03:07 | 5292 | 5.83 | 21:05:31 | 21:46:40 | 2469 | 12.49 |
结论:
速度从5.38-〉6.22,提高了15.61%。fetch线程数目增长,优化效果在减少。
2014/7/11上午
改变优化方向:
考虑到网速的问题,放弃了用以前有3000左右的有效网站地址的国外新闻网站。改用下列网址http://bj.elanw.com/,因为初始只有一个地址。防止爬取深度过深,先爬去两层而后做为基础,再做爬取。再次爬取的层数为3层。
结果:
回 数 |
效率 | 11.61条/秒 | 全体 | Nutch | Index | |||||||||
总条数 | 每回条数 | 开始 | 终了 | 耗时 | 速度 | 开始 | 终了 | 耗时 | 速度 | 开始 | 终了 | 耗时 | 速度 | |
1 | 2830 | 2830 | 11:13:05 | 11:35:52 | 1367 | 2.07 | 11:13:05 | 11:26:40 | 815 | 3.47 | 11:28:20 | 11:35:52 | 452 | 6.26 |
2 | 43885 | 41055 | 11:36:51 | 13:07:01 | 5410 | 7.59 | 11:36:51 | 12:29:47 | 3176 | 12.93 | 12:31:55 | 13:07:01 | 2106 | 19.49 |
3 | 83074 | 39189 | 13:08:11 | 14:27:47 | 4776 | 8.21 | 13:08:11 | 14:00:53 | 3162 | 12.39 | 14:02:53 | 14:27:47 | 1494 | 26.23 |
结论:
速度从6.22-〉11.61,提高了86.66%。可见访问网站的速度对爬虫有很大影响。
2014/7/11下午
优化方向:
统计了一下上午爬虫每一个阶段的详细数据,结果以下:
Inject | Generate | Fetch | Parse | CrawlDB | Link inversion | Dedup | Index | Cleanup index |
11:13:05 | 11:14:54 | 11:16:22 | 11:21:51 | 11:23:25 | 11:24:34 | 11:26:40 | 11:28:20 | 11:35:52 |
0:01:49 | 0:01:28 | 0:05:29 | 0:01:34 | 0:01:09 | 0:02:06 | 0:01:40 | 0:07:32 | 0:00:59 |
11:36:51 | 11:36:51 | 11:38:38 | 12:11:34 | 12:21:58 | 12:23:39 | 12:29:47 | 12:31:55 | 13:07:01 |
0:01:47 | 0:32:56 | 0:10:24 | 0:01:41 | 0:06:08 | 0:02:08 | 0:35:06 | 0:01:10 | |
13:08:11 | 13:08:11 | 13:09:56 | 13:41:31 | 13:50:56 | 13:52:27 | 14:00:53 | 14:02:53 | 14:27:47 |
0:01:45 | 0:31:35 | 0:09:25 | 0:01:31 | 0:08:26 | 0:02:00 | 0:24:54 |
从结果上看:fetch和index所耗时间占每次爬取时间的80%左右,因此重点考虑fetch的参数优化。
另外,察看资料发现以前Nutch的配置有个优化项目设置不对,Nutch1.8中不是fetcher.threads.per.host而是fetcher.threads.per.queue。
优化内容:
<property>
<name>fetcher.threads.per.queue</name>
<value>5</value>
</property>
<property>
<name>fetcher.queue.depth.multiplier</name>
<value>100</value>
</property>
<property>
<name>fetcher.server.delay</name>
<value>2.0</value>
</property>
<property>
<name>fetcher.server.min.delay</name>
<value>1.0</value>
</property>
结果:
回 数 |
效率 | 13.87条/秒 | 全体 | Nutch | Index | |||||||||
总条数 | 每回条数 | 开始 | 终了 | 耗时 | 速度 | 开始 | 终了 | 耗时 | 速度 | 开始 | 终了 | 耗时 | 速度 | |
1 | 2238 | 2238 | 14:38:05 | 14:56:37 | 1112 | 2.01 | 14:38:05 | 14:48:07 | 602 | 3.72 | 14:49:43 | 14:56:37 | 414 | 5.41 |
2 | 43704 | 41466 | 14:57:25 | 16:21:00 | 5015 | 8.27 | 14:57:25 | 15:43:12 | 2747 | 15.10 | 15:44:52 | 16:21:00 | 2168 | 19.13 |
3 | 82269 | 38565 | 16:21:25 | 17:34:21 | 4376 | 8.81 | 16:21:25 | 17:04:29 | 2584 | 14.92 | 17:06:24 | 17:34:21 | 1677 | 23.00 |
结论:
速度从11.61-〉13.87,提高了19.47%。可见fetch的参数优化对总体爬虫效率有不小的影响。
2014/7/11晚上
优化内容:fetch参数
<property>
<name>fetcher.threads.per.queue</name>
<value>10</value>
</property>
<property>
<name>fetcher.queue.depth.multiplier</name>
<value>200</value>
</property>
<property>
<name>fetcher.threads.fetch</name>
<value>200</value>
</property>
结果:
回 数 |
效率 | 14.52条/秒 | 全体 | Nutch | Index | |||||||||
总条数 | 每回条数 | 开始 | 终了 | 耗时 | 速度 | 开始 | 终了 | 耗时 | 速度 | 开始 | 终了 | 耗时 | 速度 | |
1 | 2224 | 2224 | 18:07:04 | 18:23:59 | 1015 | 2.19 | 18:07:04 | 18:16:33 | 569 | 3.91 | 18:18:07 | 18:23:59 | 352 | 6.32 |
2 | 42079 | 39855 | 18:24:46 | 19:35:45 | 4259 | 9.36 | 18:24:46 | 19:07:15 | 2549 | 15.64 | 19:09:02 | 19:35:45 | 1603 | 24.86 |
3 | 83466 | 41387 | 19:36:47 | 20:46:35 | 4188 | 9.88 | 19:36:47 | 20:20:37 | 2630 | 15.74 | 20:22:24 | 20:46:35 | 1451 | 28.52 |
结论:
速度从13.87-〉14.52,提高了4.69%。可见fetch的参数优化对总体爬虫效率有影响,但效果已经减少
总结:
经过这几天的优化,使得爬虫效率从4.14条/秒提高到了14.52条/秒,速度提高250.72%
1,Nutch爬虫总体过程当中,fetch和index建立占据着总体爬取时间的80%左右,fetch:55%,index:35%
fetch方面主要考虑参数优化,nutch1.8种有10多个参数,上述已经作了部分优化。
index建立的优化主要考虑作solr集群,如今仍是单机版。是从此的优化方向
2,Hadoop的相关优化,要事先作完,特别是虚拟内存和物理内存的优化,不然在优化1时会出现内存溢出,IO异常等错误
3,爬取网站的访问速度对爬虫效率有很大影响,这个很容易理解
4,从每次爬虫的速度来看,种子数量对爬虫速度有很大的影响。爬虫官方目标是每月几十亿,暂算30亿的话,天天1亿网页爬取量来算,每秒要爬取1100多网页。若是其余因素都很理想得状态下,种子数量的多少对爬虫速度有很是大的影响。实际实践效率数据:天天200万网页,每秒20多条网页。