在hadoop的框架中,刚入门我们维护好Mapper和Reducer两个类就可以实现倒排索引。作为练习可以下载20 Newsgroups数据 :http://qwone.com/~jason/20Newsgroups/。
这些文章是零散的,不适合在hadoop上跑,不过可以整合成一个或几个大文件或者抽出一小部分测试一下。
亲测:没整合,在hadoop上跑所有的文章19997篇,16g内存差点跑爆、、、
因此只是测试,为了省事Mapper、Reducer和Main全写到一个WordCount类里了。
1>worldcount是主要运行程序。
public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "word count"); job.setJarByClass(WordCount.class); job.setMapperClass(TokenizerMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); Path path = new Path(args[0]); // FileSystem fs = FileSystem.get(conf); //真分布式 FileSystem fs = path.getFileSystem(conf);//伪分布式 if (fs.exists(path)) { //遍历目录内文件,这里目录内还有一级,参数为目录路径 FileStatus[] fileStatus = fs.listStatus(path); for (FileStatus fileStatus1 : fileStatus) { FileStatus[] fileStatus2 = fs.listStatus(fileStatus1.getPath()); for (FileStatus fileStatu : fileStatus2) { // System.out.println(fileStatu.getPath().toString()); FileInputFormat.addInputPath(job, fileStatu.getPath()); } } } fs.close(); // FileInputFormat.addInputPath(job,new Path(args[0])); //单跑文件,参数为文件路径 FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); }
注意文件系统的实例化方式,真分布和假分布式不一样,假分布式用真分布式会报错:
Exception in thread "main" java.lang.IllegalArgumentException: Wrong FS: hdfs://localhost:9000/user/hadoop/input3, expected: file:///
相关连接:https://blog.csdn.net/huangjing_whlg/article/details/39341643
2>mapper,我使用了lucene进行分词。StopAnalyzer+PorterStemFilter,进行分词+词干提取。相关包可以在porn.xml依赖。注释的是普通分类器,可以都试一下比较结果。
public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text(); private FileSplit split; public void map(Object key, Text value, Context context ) throws IOExc