Hadoop編程基于MR程序?qū)崿F(xiàn)倒排索引示例
相信接觸過(guò)搜索引擎開(kāi)發(fā)的同學(xué)對(duì)倒排索引并不陌生,谷歌、百度等搜索引擎都是用的倒排索引,關(guān)于倒排索引的有關(guān)知識(shí),這里就不再深入講解,有興趣的同學(xué)到網(wǎng)上了解一下。這篇博文就帶著大家一起學(xué)習(xí)下如何利用Hadoop的MR程序來(lái)實(shí)現(xiàn)倒排索引的功能。
一、數(shù)據(jù)準(zhǔn)備
1、輸入文件數(shù)據(jù)
這里我們準(zhǔn)備三個(gè)輸入文件,分別如下所示
a.txt
hello tom hello jerry hello tom
b.txt
hello jerry hello jerry tom jerry
c.txt
hello jerry hello tom
2、最終輸出文件數(shù)據(jù)
最終輸出文件的結(jié)果為:
[plain] view plain copy hello c.txt-->2 b.txt-->2 a.txt-->3 jerry c.txt-->1 b.txt-->3 a.txt-->1 tom c.txt-->1 b.txt-->1 a.txt-->2
二、倒排索引過(guò)程分析
根據(jù)輸入文件數(shù)據(jù)和最終的輸出文件結(jié)果可知,此程序需要利用兩個(gè)MR實(shí)現(xiàn),具體流程可總結(jié)歸納如下:
-------------第一步Mapper的輸出結(jié)果格式如下:-------------------- context.wirte("hello->a.txt", "1") context.wirte("hello->a.txt", "1") context.wirte("hello->a.txt", "1") context.wirte("hello->b.txt", "1") context.wirte("hello->b.txt", "1") context.wirte("hello->c.txt", "1") context.wirte("hello->c.txt", "1") -------------第一步Reducer的得到的輸入數(shù)據(jù)格式如下:------------- <"hello->a.txt", {1,1,1}> <"hello->b.txt", {1,1}> <"hello->c.txt", {1,1}> -------------第一步Reducer的輸出數(shù)據(jù)格式如下--------------------- context.write("hello->a.txt", "3") context.write("hello->b.txt", "2") context.write("hello->c.txt", "2") -------------第二步Mapper得到的輸入數(shù)據(jù)格式如下:----------------- context.write("hello->a.txt", "3") context.write("hello->b.txt", "2") context.write("hello->c.txt", "2") -------------第二步Mapper輸出的數(shù)據(jù)格式如下:-------------------- context.write("hello", "a.txt->3") context.write("hello", "b.txt->2") context.write("hello", "c.txt->2") -------------第二步Reducer得到的輸入數(shù)據(jù)格式如下:----------------- <"hello", {"a.txt->3", "b.txt->2", "c.txt->2"}> -------------第二步Reducer輸出的數(shù)據(jù)格式如下:----------------- context.write("hello", "a.txt->3 b.txt->2 c.txt->2") 最終結(jié)果為: hello a.txt->3 b.txt->2 c.txt->2
三、程序開(kāi)發(fā)
3.1、第一步MR程序與輸入輸出
package com.lyz.hdfs.mr.ii; import java.io.IOException; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.input.FileSplit; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /** * 倒排索引第一步Map Reduce程序,此處程序?qū)⑺械腗ap/Reduce/Runner程序放在一個(gè)類中 * @author liuyazhuang * */ public class InverseIndexStepOne { /** * 完成倒排索引第一步的mapper程序 * @author liuyazhuang * */ public static class StepOneMapper extends Mapper<LongWritable, Text, Text, LongWritable>{ @Override protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws IOException, InterruptedException { //獲取一行數(shù)據(jù) String line = value.toString(); //切分出每個(gè)單詞 String[] fields = StringUtils.split(line, " "); //獲取數(shù)據(jù)的切片信息 FileSplit fileSplit = (FileSplit) context.getInputSplit(); //根據(jù)切片信息獲取文件名稱 String fileName = fileSplit.getPath().getName(); for(String field : fields){ context.write(new Text(field + "-->" + fileName), new LongWritable(1)); } } } /** * 完成倒排索引第一步的Reducer程序 * 最終輸出結(jié)果為: * hello-->a.txt 3 hello-->b.txt 2 hello-->c.txt 2 jerry-->a.txt 1 jerry-->b.txt 3 jerry-->c.txt 1 tom-->a.txt 2 tom-->b.txt 1 tom-->c.txt 1 * @author liuyazhuang * */ public static class StepOneReducer extends Reducer<Text, LongWritable, Text, LongWritable>{ @Override protected void reduce(Text key, Iterable<LongWritable> values, Reducer<Text, LongWritable, Text, LongWritable>.Context context) throws IOException, InterruptedException { long counter = 0; for(LongWritable value : values){ counter += value.get(); } context.write(key, new LongWritable(counter)); } } //運(yùn)行第一步的MR程序 public static void main(String[] args) throws Exception{ Configuration conf = new Configuration(); Job job = Job.getInstance(conf); job.setJarByClass(InverseIndexStepOne.class); job.setMapperClass(StepOneMapper.class); job.setReducerClass(StepOneReducer.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(LongWritable.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); FileInputFormat.addInputPath(job, new Path("D:/hadoop_data/ii")); FileOutputFormat.setOutputPath(job, new Path("D:/hadoop_data/ii/result")); job.waitForCompletion(true); } }
3.1.1 輸入數(shù)據(jù)
a.txt
hello tom hello jerry hello tom
b.txt
hello jerry hello jerry tom jerry
c.txt
hello jerry hello tom
3.1.2
輸出結(jié)果:
hello-->a.txt 3 hello-->b.txt 2 hello-->c.txt 2 jerry-->a.txt 1 jerry-->b.txt 3 jerry-->c.txt 1 tom-->a.txt 2 tom-->b.txt 1 tom-->c.txt 1
3.2 第二步MR程序與輸入輸出
package com.lyz.hdfs.mr.ii; import java.io.IOException; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /** * 倒排索引第二步Map Reduce程序,此處程序?qū)⑺械腗ap/Reduce/Runner程序放在一個(gè)類中 * @author liuyazhuang * */ public class InverseIndexStepTwo { /** * 完成倒排索引第二步的mapper程序 * * 從第一步MR程序中得到的輸入信息為: * hello-->a.txt 3 hello-->b.txt 2 hello-->c.txt 2 jerry-->a.txt 1 jerry-->b.txt 3 jerry-->c.txt 1 tom-->a.txt 2 tom-->b.txt 1 tom-->c.txt 1 * @author liuyazhuang * */ public static class StepTwoMapper extends Mapper<LongWritable, Text, Text, Text>{ @Override protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context) throws IOException, InterruptedException { String line = value.toString(); String[] fields = StringUtils.split(line, "\t"); String[] wordAndFileName = StringUtils.split(fields[0], "-->"); String word = wordAndFileName[0]; String fileName = wordAndFileName[1]; long counter = Long.parseLong(fields[1]); context.write(new Text(word), new Text(fileName + "-->" + counter)); } } /** * 完成倒排索引第二步的Reducer程序 * 得到的輸入信息格式為: * <"hello", {"a.txt->3", "b.txt->2", "c.txt->2"}>, * 最終輸出結(jié)果如下: * hello c.txt-->2 b.txt-->2 a.txt-->3 jerry c.txt-->1 b.txt-->3 a.txt-->1 tom c.txt-->1 b.txt-->1 a.txt-->2 * @author liuyazhuang * */ public static class StepTwoReducer extends Reducer<Text, Text, Text, Text>{ @Override protected void reduce(Text key, Iterable<Text> values, Reducer<Text, Text, Text, Text>.Context context) throws IOException, InterruptedException { String result = ""; for(Text value : values){ result += value + " "; } context.write(key, new Text(result)); } } //運(yùn)行第一步的MR程序 public static void main(String[] args) throws Exception{ Configuration conf = new Configuration(); Job job = Job.getInstance(conf); job.setJarByClass(InverseIndexStepTwo.class); job.setMapperClass(StepTwoMapper.class); job.setReducerClass(StepTwoReducer.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(Text.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); FileInputFormat.addInputPath(job, new Path("D:/hadoop_data/ii/result/part-r-00000")); FileOutputFormat.setOutputPath(job, new Path("D:/hadoop_data/ii/result/final")); job.waitForCompletion(true); } }
3.2.1 輸入數(shù)據(jù)
hello-->a.txt 3 hello-->b.txt 2 hello-->c.txt 2 jerry-->a.txt 1 jerry-->b.txt 3 jerry-->c.txt 1 tom-->a.txt 2 tom-->b.txt 1 tom-->c.txt 1
3.2.2 輸出結(jié)果
hello c.txt-->2 b.txt-->2 a.txt-->3 jerry c.txt-->1 b.txt-->3 a.txt-->1 tom c.txt-->1 b.txt-->1 a.txt-->2
總結(jié)
以上就是本文關(guān)于Hadoop編程基于MR程序?qū)崿F(xiàn)倒排索引示例的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:Hadoop對(duì)文本文件的快速全局排序?qū)崿F(xiàn)方法及分析、hadoop重新格式化HDFS步驟解析、淺談七種常見(jiàn)的Hadoop和Spark項(xiàng)目案例等,有什么問(wèn)題可以直接留言,小編會(huì)及時(shí)回復(fù)大家的。感謝朋友們對(duì)本站的支持!
相關(guān)文章
Hadoop對(duì)文本文件的快速全局排序?qū)崿F(xiàn)方法及分析
這篇文章主要介紹了Hadoop對(duì)文本文件的快速全局排序?qū)崿F(xiàn)方法及分析,小編覺(jué)得挺不錯(cuò)的,這里分享給大家,供需要的朋友參考。2017-10-10Spark簡(jiǎn)介以及與Hadoop對(duì)比分析
這篇文章主要對(duì)Spark作了詳細(xì)的簡(jiǎn)介,包含spark的生態(tài)系統(tǒng)、基本感念、架構(gòu)設(shè)計(jì)、部署應(yīng)用,以及與Hadoop作了對(duì)比,分析其優(yōu)劣特點(diǎn),有需要的朋友可以參考下2021-08-08淺談七種常見(jiàn)的Hadoop和Spark項(xiàng)目案例
這篇文章主要介紹了淺談七種常見(jiàn)的Hadoop和Spark項(xiàng)目案例,小編覺(jué)得挺不錯(cuò)的,這里分享給大家,需要的朋友可以了解下。2017-10-10搭建Consul服務(wù)發(fā)現(xiàn)與服務(wù)網(wǎng)格
這篇文章介紹了搭建Consul服務(wù)發(fā)現(xiàn)與服務(wù)網(wǎng)格的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04Hadoop編程基于MR程序?qū)崿F(xiàn)倒排索引示例
最近正在學(xué)習(xí)Hadoop的知識(shí),一步步來(lái),這里先給大家分享一篇關(guān)于Hadoop編程基于MR程序?qū)崿F(xiàn)倒排索引的文章,還是不錯(cuò)的,供需要的朋友參考。2017-10-10hadoop動(dòng)態(tài)增加和刪除節(jié)點(diǎn)方法介紹
這篇文章主要介紹了hadoop動(dòng)態(tài)增加和刪除節(jié)點(diǎn)方法介紹,小編覺(jué)得挺不錯(cuò)的,這里分享給大家,需要的朋友可以參考。2017-10-10