job1
map Selector
输入目录为crawldb/current
输入key:Text 为url ,Value:CrawlDatum
功能如下
1 如果filter为true URLFilter过滤,如果过滤的后的url为空返回
2 调用(!schedule.shouldFetch(url, crawlDatum, curTime)方法计算是不是要fetch 逻辑是看value的当前fetchtime和当前时间的比较,大于返回true,否则为false,这里有个逻辑是如果当前value的fetchtime减去当前时间大约最大间隔时间,并且当前的value的间隔时间大于最大间隔时间重新设置。代码如下
// pages are never truly GONE - we have to check them from time to time.
// pages with too long fetchInterval are adjusted so that they fit within
// maximum fetchInterval (segment retention period).
if (datum.getFetchTime() - curTime > (long) maxInterval * 1000) {
if (datum.getFetchInterval() > maxInterval) {
datum.setFetchInterval(maxInterval * 0.9f);
}
datum.setFetchTime(curTime);
}
if (datum.getFetchTime() > curTime) {
return false; // not time yet
}
return true;
}
返回false 则返回
3 如果已经有fetch value的meta 会被写入Nutch.WRITABLE_GENERATE_TIME_KEY 的key 值为上次这个map的时间,这个上次写入时间与当前时间的差值和间隔时间配置crawl.gen.delay的值比较,如果大于这个时间,才能fetch
4 sort = scfilters.generatorSortValue((Text) key, crawlDatum, sort);这个 scfilters最后调用OPICScoringFilter计算分数,是逻辑是当前value:crawlDatum 的datum.getScore() * sort,如果计算的sort 小于generate.min.score 这个配置的值返回
5 写入 key:FloatWritable value:SelectorEntry ,设置value 元数据的generator的时间 key为Nutch.WRITABLE_GENERATE_TIME_KEY,值为当前时间
key 是步骤4中的sort ,代码如下
sortValue.set(sort);
// record generation time
crawlDatum.getMetaData().put(Nutch.WRITABLE_GENERATE_TIME_KEY, genTime);
entry.datum = crawlDatum;
entry.url = (Text) key;
output.collect(sortValue, entry); // invert for sort by score
6 这里有个设置 job.setPartitionerClass(Selector.class);使用URLPartitioner split,这个根据配置partition.url.mode 根据ip或者domain 取hash
reduce Selector
1 topN ,这个值设置的一个segment的数据大小,如果一个segment大于这个值,如果有下一个segment,则取下一个segment,否则返回
2 如设置了normalise为true normalizers不为空,调用normalize
3 根据这个key:generate.count.mode,确定分组模式 是域名还是ip。
4 根据这个generate.max.count 配置看 每个ip或域名分组在单个segment里面最大的值,如果为-1 则不检查,如果不为-1,超过这个值,写入下个segment,如果没有segment了。舍弃这个url。否则设置value的segment,entry.segnum = new IntWritable(hostCount[0]),如果为-1 直接设置segment entry.segnum = new IntWritable(currentsegmentnum);
4 写入key :FloatWritable ,value:SelectorEntry ruduce的输出目录 Path tempDir = new Path(getConf().get("mapred.temp.dir", ".") + "/generate-temp-"
+ System.currentTimeMillis());
5 reduce 设置了key的 Comparator DecreasingFloatComparator,不用转换对象进行字节比较
类如下
public static class DecreasingFloatComparator extends FloatWritable.Comparator {
/** Compares two FloatWritables decreasing. */
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return super.compare(b2, s2, l2, b1, s1, l1);
}
}
6 设置 job.setOutputFormat(GeneratorOutputFormat.class); 代码如下,取得文件名字
// Allows the reducers to generate one subfile per
public static class GeneratorOutputFormat extends
MultipleSequenceFileOutputFormat<FloatWritable,SelectorEntry> {
// generate a filename based on the segnum stored for this entry
protected String generateFileNameForKeyValue(FloatWritable key, SelectorEntry value,
String name) {
return "fetchlist-" + value.segnum.toString() + "/" + name;
}
}
partitionSegment job
map :SelectorInverseMapper
输入目录为上个job的输出目录下面的以fetchlist-segment 的目录
1 map 主要是 将 k-v的转换,key:Text 为url value:SelectorEntry
代码如下
public void map(FloatWritable key, SelectorEntry value,
OutputCollector<Text,SelectorEntry> output, Reporter reporter) throws IOException {
SelectorEntry entry = (SelectorEntry) value;
output.collect(entry.url, entry);
}
2 job.setPartitionerClass(URLPartitioner.class);
reduce : PartitionReducer
输出目录 crawl/segments/当前时间/crawl_generate 例如:crawl/segments/20120716172043/crawl_generate
1 ruduce只是做的k-v的转换 key:Text 为url,value:CrawlDatum
代码如下
public void reduce(Text key, Iterator<SelectorEntry> values,
OutputCollector<Text,CrawlDatum> output, Reporter reporter) throws IOException {
// if using HashComparator, we get only one input key in case of
// hash collision
// so use only URLs from values
while (values.hasNext()) {
SelectorEntry entry = values.next();
output.collect(entry.url, entry.datum);
}
}
2 设置 job.setOutputKeyComparatorClass(HashComparator.class);
删除第一个job的输出目录
如果设置了generate.update.crawldb 为true则运行第三个job
map :CrawlDbUpdater
输入目录为第二个job的输出目录,即生成的segment目录里面的crawl_generate目录例如 :crawl\segments\20120711150527\crawl_generate和/crawldb/current 目录,
1 map只是合并目录
reduce :CrawlDbUpdater 去重复,保证一个url只有一条记录
输出目录
// update the db from tempDir
Path tempDir2 = new Path(getConf().get("mapred.temp.dir", ".") + "/generate-temp-"
+ System.currentTimeMillis());
最后调用 CrawlDb.install(job, dbDir); 更新当前crawldb
删除 这个job的输出文件
- 大小: 120.3 KB
- 大小: 36.2 KB
- 大小: 18.8 KB
分享到:
相关推荐
nutcher 是 Apache Nutch 的中文教程,在... Nutch流程控制源码详解(bin/crawl中文注释版) Nutch教程——URLNormalizer源码详解 Nutch参数配置——http.content.limit 文档截图:
四、Nutch工作流详解 Nutch的工作流程包括多个步骤,如生成段(Segments)、迭代抓取(Fetch)、解析(Parse)、更新链接数据库(Update)、生成新的种子(Generate)、选择待抓取页面(Select)、重定向处理(Fetch...
### 二、Eclipse配置Nutch的步骤详解 #### 步骤1:创建Nutch项目 首先,在Eclipse中创建一个新的Java项目,选择“File > New > Project > Java project”,然后点击“Next”。在创建项目时,选择“Create project ...
Apache Nutch 是一个开源的网络爬虫框架,用于抓取互联网上的网页并生成索引,以便于搜索引擎使用。本文将详细介绍如何在Windows环境下配置Nutch 1.4,并使用Eclipse进行开发。以下是你需要知道的关键步骤: 1. **...
Nutch的工作流程主要包括以下几个阶段:注入(Injector)、生成抓取URL(Generator)、网页抓取(Fetcher)、网页解析(ParseSegment)、数据库更新(CrawlDb)、链接数据库处理(LinkDb)以及索引构建(Indexer)。...
【Nutch安装详解】 Nutch是一款开源的网络爬虫软件,用于抓取互联网上的网页并构建搜索引擎。本文将详细介绍如何安装Nutch version 0.8。 **1. 安装前提** 在开始Nutch的安装前,需要确保满足以下硬件和软件条件...
分布式搜索引擎Nutch开发详解 Nutch是一款开源的、基于Java实现的全文搜索引擎,它主要用于构建大规模的网络爬虫系统,并提供了对抓取的网页进行索引和搜索的功能。Nutch与Hadoop紧密集成,能够充分利用分布式计算...
#### Nutch架构详解 Nutch的架构设计可以分为两个主要部分:抓取器(Crawler)和搜索器(Searcher)。抓取器负责抓取网页内容,而搜索器则负责处理用户的查询请求。具体来说: 1. **抓取器**:抓取器的工作流程...
【Nutch 知识点详解】 Nutch 是一个开源的 Java 搜索引擎,它提供了从爬虫到搜索的全套工具,使用户能够构建自己的搜索引擎。Nutch 的主要组成部分包括两个关键角色:Crawler 和 Searcher。 1. **Crawler**: ...
**Nutch 概述** Nutch 是一个开源的网络爬虫项目,主要设计用于抓取、索引和搜索互联网上的网页。它由 Apache 软件基金会开发,并且是 Hadoop 的一部分,这意味着它能够利用分布式计算来处理大规模的数据抓取任务。...
Apache Nutch 是一个开源的网络爬虫框架,用于抓取互联网上的网页并建立索引,以便进行全文搜索。Nutch 2.2.1 是一个稳定版本,它依赖于其他几个组件来完成其功能,包括 Apache Ant、Apache Tomcat、Java 开发工具包...
Nutch各个配置项的详细说明,非常详细的说明了每一项
#### 二、Nutch插件开发详解 Nutch插件的开发涉及到以下几个关键步骤: 1. **创建插件目录结构**:插件源代码通常位于`src/plugin`目录下,目录名称通常与插件ID一致。例如,如果插件ID为`index-field`,则目录...