MapReduce 算法设计-Inverted Indexing

倒排索引是搜索引擎关键技术,通过MapReduce处理大规模数据。Mapper端对文章分词并形成postings,Reducer端接收term及postings,排序存储。但原始算法内存限制明显,解决方案是调整mapper输出key格式。程序实现涉及自定义FileInputFormat和分词处理,运行时可能遇到类找不到和Writable构造函数缺失问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 概述

倒排索引是搜索引擎中不可或缺的数据结构,利用倒排索引可以快速搜索到包涵搜索关键词的一系列文章。倒排索引的常见结构如下图:

常见倒排索引结构

在倒排索引中,每个term与一系列的postings相关联,每个postings由文章的id以及payload组成,而payload常见的是该词在该文章中的词频,有的也加上了位置信息。

2 算法机理

使用MapReduce进行倒排索引的构造是目前大多数大数据公司所采用的方式,因为其可以很好地处理大规模的数据。最基本的倒排索引MapReduce算法如下:

基本的MapReduce实现的倒排索引算法

在该算法中,mapper端的输入是doc id以及doc content,每篇文章都倍分配给一个mapper,在mapper端先对文章进行分词,统计词频等,然后组成postings,最后将每个词以及其对应的postings发送出去; reducer端接收一个term,以及其对应的一系列postings,将每一个postings加入一个列表中,然后对该列表按照doc id排序,最后发送term和其对应的postings列表。 处理流程可见下面的示意图:

倒排索引构建示意图

然而,你估计也已经发现了,上述的算法存在一个很明显的可扩展性瓶颈,就是在reducer端它假设有足够大的内存来储存每一个term对应的一系列postings,因为后续还要对这些postings进行排序。因而,当postings变得很大时,reducer端将会耗尽内存。

一个很简单的解决方案是:我们改变mapper端发送出的key的格式,将key的格式变为

3 程序实现

从上部分可以看出,使用MapReduce实现倒排索引的构建原理其实并不是很复杂,然而在实现中还是有一些问题需要注意的。

  1. 从算法中我们可以看到,mapper的输入是key是doc id,value为doc的内容,那么如何保证在分片时能恰好按每篇文章分成各个分片传给mapper?
  2. 中文文章的分词如何处理?

第二个问题比较容易,我们可以使用第三方分词包来进行文章的分词处理,我这里使用的是ansj中文分词

第一个问题比较复杂一点,我们需要重定义一个FileInputFormat,使用该FileInputFormat mapper可以把整个文件当作一条记录处理。下面代码实现了一个WholeFileInputFormat。

package mp.invertedIndexing;

import java.io.IOException;

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.ap
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值