环境:
  Hadoop1.x,CentOS6.5,三台虚拟机搭建的模拟分布式环境

  数据:任意数量、格式的文本文件(我用的四个.java代码文件)

方案目标:

  根据提供的文本文件,提取出每个单词在哪个文件中出现了几次,组成倒排索引,格式如下

  Ant FaultyWordCount.java : 1 , WordCount.java : 1

思路:

  因为这个程序需要用到三个变量:单词、文件名、出现的频率,因此需要自定义Writable类,以单词为key,将文件名和出现的频率打包。

  1.先将每行文本的单词进行分割,以K/V=Word/Filename:1的格式分割。

  2.利用Combiner类,将本Map一个文件的先进行一次计数,减少传输量

  3.在Reduce中对Combiner中传输过来的同一个单词的在不同文件出现的频率数据进行组合。

难点:这个程序主要是用到了一个Combiner和自定义了Writable类。在实现的时候,需要注意的是Writable必须默认无参构造函数。

主调用Main类:

package ren.snail;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner; public class Main extends Configured implements Tool { public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
int result = ToolRunner.run(new Configuration(), new Main(), args);
System.exit(result);
} @Override
public int run(String[] arg0) throws Exception {
// TODO Auto-generated method stub
Configuration configuration = getConf();
Job job = new Job(configuration, "InvertIndex");
job.setJarByClass(Main.class);
FileInputFormat.addInputPath(job, new Path(arg0[0]));
FileOutputFormat.setOutputPath(job, new Path(arg0[1])); job.setMapperClass(InvertMapper.class);
job.setCombinerClass(Combinner.class); //设置Combiner类
job.setReducerClass(InvertReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(FileFreqWritable.class);
System.exit(job.waitForCompletion(true) ? 0 : 1);
return 0;
} }

自定义Writbale类

package ren.snail;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable; public class FileFreqWritable implements Writable {
Text documentID;
IntWritable fequence; public FileFreqWritable() //必须提供无参构造函数
{
this.documentID = new Text();
this.fequence = new IntWritable();
}
public FileFreqWritable(Text id,IntWritable feq) {
// TODO Auto-generated constructor stub
this.documentID=id;
this.fequence =feq;
} public void set(String id,int feq)
{
this.documentID.set(id);
this.fequence.set(feq);
} @Override
public void readFields(DataInput in) throws IOException {
// TODO Auto-generated method stub
documentID.readFields(in);
fequence.readFields(in); } @Override
public void write(DataOutput out) throws IOException {
// TODO Auto-generated method stub
documentID.write(out);
fequence.write(out);
} public Text getDocumentID() {
return documentID;
} public String toString()
{
return documentID.toString()+" : "+fequence.get();
}
public IntWritable getFequence() {
return fequence;
} }

Map

package ren.snail;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit; public class InvertMapper extends Mapper<LongWritable, Text, Text, FileFreqWritable>{
public void map(LongWritable key,Text value,Context context) throws IOException,InterruptedException
{
String data = value.toString().replaceAll("[^a-zA-Z0-9]+", " "); //将不需要的其他字符都设为空
String[] values = data.split(" ");
FileSplit fileSplit = (FileSplit)context.getInputSplit();
String filename = fileSplit.getPath().getName();
for (String temp : values) {
FileFreqWritable obj = new FileFreqWritable(new Text(filename),new IntWritable(1));
context.write(new Text(temp), obj);
} }
}

Combiner

package ren.snail;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; public class Combinner extends Reducer<Text, FileFreqWritable, Text, FileFreqWritable>{
public void reduce(Text key,Iterable<FileFreqWritable> values,Context context) throws IOException,InterruptedException
{
int count = 0 ;
String id = "";
for (FileFreqWritable temp : values) {
count++;
if(count == 1)
{
id=temp.getDocumentID().toString();
}
}
context.write(key,new FileFreqWritable(new Text(id), new IntWritable(count)));
}
}

Reduce

package ren.snail;

import java.io.IOException;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; public class InvertReducer extends Reducer<Text, FileFreqWritable, Text, Text> { public void reduce(Text key,Iterable<FileFreqWritable> values,Context context) throws IOException,InterruptedException {
StringBuilder value = new StringBuilder();
for (FileFreqWritable fileFreqWritable : values) {
String temp = fileFreqWritable.toString();
value.append(temp+" , ");
}
context.write(key,new Text(value.toString()));
}
}

其实我的Reduce实现思路可能有点问题,不过大致是这样

MapReduce实例-倒排索引的更多相关文章

  1. MapReduce的倒排索引

    MapReduce的倒排索引 索引: 什么是索引:索引(Index)是帮助数据库高效获取数据的数据结构.索引是在基于数据库表创建的,它包含一个表中某些列的值以及记录对应的地址,并且把这些值存储在一个数 ...

  2. MapReduce实例2(自定义compare、partition)& shuffle机制

    MapReduce实例2(自定义compare.partition)& shuffle机制 实例:统计流量 有一份流量数据,结构是:时间戳.手机号.....上行流量.下行流量,需求是统计每个用 ...

  3. MapReduce实例&YARN框架

    MapReduce实例&YARN框架 一个wordcount程序 统计一个相当大的数据文件中,每个单词出现的个数. 一.分析map和reduce的工作 map: 切分单词 遍历单词数据输出 r ...

  4. 利用MapReduce实现倒排索引

    这里来学习的是利用MapReduce的分布式编程模型来实现简单的倒排索引. 首先什么是倒排索引? 倒排索引是文档检索中最常用的数据结构,被广泛地应用于全文搜索引擎. 它主要是用来存储某个单词(或词组) ...

  5. MapReduce实例浅析

    在文章<MapReduce原理与设计思想>中,详细剖析了MapReduce的原理,这篇文章则通过实例重点剖析MapReduce 本文地址:http://www.cnblogs.com/ar ...

  6. MapReduce实例

    1.WordCount(统计单词) 经典的运用MapReuce编程模型的实例 1.1 Description 给定一系列的单词/数据,输出每个单词/数据的数量 1.2 Sample a is b is ...

  7. mapreduce (三) MapReduce实现倒排索引(二)

    hadoop api http://hadoop.apache.org/docs/r1.0.4/api/org/apache/hadoop/mapreduce/Reducer.html 改变一下需求: ...

  8. MapReduce实战--倒排索引

    本文地址:http://www.cnblogs.com/archimedes/p/mapreduce-inverted-index.html,转载请注明源地址. 1.倒排索引简介 倒排索引(Inver ...

  9. Hadoop实战-MapReduce之倒排索引(八)

    倒排索引 (就是key和Value对调的显示结果) 一.需求:下面是用户播放音乐记录,统计歌曲被哪些用户播放过 tom        LittleApple jack       YesterdayO ...

随机推荐

  1. Android中GPS定位的简单应用

    在Android中通过GPS获得当前位置,首先要获得一个LocationManager实例,通过该实例的getLastKnownLocation()方法获得第一个的位置,该方法的说明如下: void ...

  2. FNV哈希算法

    由来:FNV哈希算法全名为Fowler-Noll-Vo算法,是以三位发明人Glenn Fowler,Landon Curt Noll,Phong Vo的名字来命名的,最早在1991年提出. 特点和用途 ...

  3. NOSQL学习笔记系列之MongoDB 一 基础

    主题:MongoDB 学习资料参考网址: 1.http://www.w3cschool.cc/mongodb/mongodb-tutorial.html 2.http://www.icoolxue.c ...

  4. Java --ClassLoader创建、加载class、卸载class

    一.java提供了三种ClassLoader对Class进行加载: 1.BootStrap ClassLoader:称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库 ...

  5. 【USACO】DP动态规划小测(一)

    {20160927 19:30~21:30} 总分400分,我113.33,稳稳地垫底了......(十分呼应我上面的博客名,hhh~)过了这么多天我才打完所有代码,废话我也就不多说了.不过,虽然时间 ...

  6. PHP知识库图谱汇总(完善中)

    基本语法不做汇总 经典算法: 冒泡算法.快速算法.二分查找 字符串处理: 字符串查找 字符串排序 字符串切割 字符串定位 字符串对比 字符串大小写转换 Session和Cookies: Session ...

  7. TestNG官方文档中文版(5)-测试方法/类和组

    5 - Test methods, Test classes and Test groups 5.1 - Test groups TestNG容许执行复杂的测试方法分组.不仅可以申明方法属于组,而且可 ...

  8. C语言之字符串处理函数

    C语言中字符串处理函数介绍 下面介绍8种基本的常用的字符串处理函数,在数值数组中也常常用到(部分函数).所有的C语言编译系统中一般都提供这些函数. 1.puts函数——输出字符串的函数 一般的形式为p ...

  9. Devrama Slider - 支持任意 HTML 的内容滑块

    Devrama Slider 是一个图片滑块,支持很多特色功能.除了支持图片滑动,其它的 HTML 内容也支持.主要特色:响应式.图片预加载.图片延迟加载.进度条.自定义导航栏和控制按钮等等. 在线演 ...

  10. Mondrian – 开源的矢量图形 Web 应用程序

    Mondrian 是一个免费矢量图形 Web 应用程序,类似 Adobe Illustrator 或 Inkscape.Mondrian 提供所有所需的工具来创建.修改和导出简单的 SVG 文件,过历 ...