索引过程-delete duplicates

去重过程同样很简单,不过需要些技巧。

正如你想的一样,在入手之前我自己也分析,怎样根据url & md5去重呢?去重又怎样实现呢?

*其中我当时想法跟job1(见下面)做法是相近的:url+time;

*而md5去重时我又觉得使用md5+time亦未尝不可,因为当时我没有考虑到score因素,但可以断定的是不能使用md5作为distinct,因为这就是题目要求;

*至于怎样去删除索引 ,当时也没有考虑:)

 

 

让我们先分析一个删除例子:

A多个urls中,如果存在相同的urls,只取最新的一个;

B如果存在相同md5的urls,只保留评分最高或url最短的一个。

 

data model:

 

url
fetch timecontentscore
a.cn 2011-1-1a2
a.cn 2011-7-1 b 4
a.cn 2011-5-1a1
b.cn2011-4-1 b 2

 

 

要么,按照A要求 ,第一轮后输出結果如下 :

a.cn
2011-7-1
b
4
b.cn
2011-4-1
b
2

 

再根据B要求,发现这两urls含有相同的content,所以再进行score筛选,結果为:

a.cn
2011-7-1
b
4

 

如果b.cn的评分比a.cn高时,则为另一結果。可见,从实际 上出发,这也是符合需求的。

因为相同的有相同的urls只取最后 一个;当有相同的content时只取score最高的一个,这样导致二种結果:

1.要么相同的urls中有一个最新的留下来了;或者

2.内容相同的url只保留score高的一个。


即取舍原则是:最新的优先;分数高的优先。NOTE:上面先url再md5这个过程是可逆的 。(可以分析一下上面的反过程,結果是一样的)

至于为什么先进行url再到md5,其实已经不太重要了?

 

*****************************

注意以上过程未严格的考虑url与content的对应关系,极端情况下,url与content 是m:n的关系,如

一个url可以对应多个content,比如页面中存在时间,不同的访问时间生成的内容不一样;

同样的content,如404页面,只要是访问了不存在的url都会进行这个页面。

******************************

 

好了,现在开始进行分析,其实上面过程也大概反应了这个dedup的过程:

1.url-distinct job

input :利用inputFormat改写了输入格式,在next()时对<url,Indexdoc>进行了数据shipping,其中indexdoc是对索引 中的doc的简单encapsulation,包括hash,score,tstamp etc.

*其中next方法遍历了所有的doc;

*同时拆分原则也是一份index一个split,这样保证在递归输入<key,value>到mapper之前 是可以让next()中的reader完整读取index,因为一个split生成一个对应 的recordReader;

*同时让url作为key也可以保证了处理需求,即上述A要求

 

mapper :use default

reducer :对url相同的进行distinct,如果是最后 个则标记为keep=true,表明是将要以md5与其它比较取舍。

 

output :<MD5Hash,indexdoc>,在reduce中对上述的key进行了转换,方便后续job处理。

 

note:这里使用了默认的partition,所以相同 的url去到想再的reducer,保证了不至于url混跑。

 

2.md5-distinct job

input:上述输出

 

mapper:default

 

partition:对md5进行hash。注意已经改写了hashCode(),只返回高四位的hash

 

reducer:将job1中标记为false的直接输出(待删除索引 );只保留true的一个(如果存在),然后与其中md5相同的url进行比对,得出score top1或min(url lengh)的一个(不输出)

 

 

output:注意些又将job1中的<md5,indexdoc>退回它的输入格式,即<url,indexdoc>

 

3.delete-index job

input:如上

mapper:对上述的输出进行转换:<index-path,docid>

reducer:根据 indexpath和docid进行删除索引。(其实这个reader不可以提取出来复用,因为这是根据 不同的indexpath进行发分的)

output:由于索引已经在red阶段已经处理了,没有输出必要,所以改写了outputformat.

 

*索引删除时是按照docid进行了,一方面增高性能;其次是如果利用url,因为可能相同的有多个(如上述)这述造成删除错误。

 

其中具体的删除流程如下图:



环境假定:

有三份索引 (所以有三个mappers)

指定二个reducers(固每次map之后都有二个r,数据均匀的理论值)

默认使用SequenceFileInputFormat(splitable)

 

 

分析 :

在job2-3之间的mappers是不确定 的,根据 当时的运行情况进行splits;

在每次map完后又恢复至二个r;

在job3,我们有理由 相信其中的一个r被分发的数据大于另一个,这是因为分发时使用了indexpath-hash来实现的。固图中浓黑色的一个数据是多的,另一个是小的;

所以由数据多的r将负责index dedup的任务就多了一个;

 

总之,一个red可以对应 多个index dedup(由于r处理时是按key按sequential order input的,所以不会出现 一份索引 被多个r处理的局面,初初看到其中的reader在每次r时构成一个感觉耗费很大,其实不然);但反之不然。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值