当前位置:   article > 正文

如何编写一个MapReduce程序统计每个单词出现次数_mapreduce统计某一个单词出现次数

mapreduce统计某一个单词出现次数

1.准备资料

1.导入相关依赖

  1. <dependencies>
  2. <!--hadoop相关依赖-->
  3. <dependency>
  4. <groupId>org.apache.hadoop</groupId>
  5. <artifactId>hadoop-client</artifactId>
  6. <version>3.1.3</version>
  7. </dependency>
  8. <!--日志相关的依赖-->
  9. <dependency>
  10. <groupId>org.slf4j</groupId>
  11. <artifactId>slf4j-log4j12</artifactId>
  12. <version>1.7.30</version>
  13. </dependency>
  14. </dependencies>

2.导入maven包管理工具,后续能帮助我们打包管理各种资源

  1. <build>
  2. <plugins>
  3. <plugin>
  4. <artifactId>maven-compiler-plugin</artifactId>
  5. <version>3.6.1</version>
  6. <configuration>
  7. <source>1.8</source>
  8. <target>1.8</target>
  9. </configuration>
  10. </plugin>
  11. <plugin>
  12. <artifactId>maven-assembly-plugin</artifactId>
  13. <configuration>
  14. <descriptorRefs>
  15. <descriptorRef>jar-with-dependencies</descriptorRef>
  16. </descriptorRefs>
  17. </configuration>
  18. <executions>
  19. <execution>
  20. <id>make-assembly</id>
  21. <phase>package</phase>
  22. <goals>
  23. <goal>single</goal>
  24. </goals>
  25. </execution>
  26. </executions>
  27. </plugin>
  28. </plugins>
  29. </build>

3.在resources资源目录下创建一个log4j2.xml的配置文件,用来 配置日志信息

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Configuration status="error" strict="true" name="XMLConfig">
  3. <Appenders>
  4. <!-- 类型名为Console,名称为必须属性 -->
  5. <Appender type="Console" name="STDOUT">
  6. <!-- 布局为PatternLayout的方式,
  7. 输出样式为[INFO] [2018-01-22 17:34:01][org.test.Console]I'm here -->
  8. <Layout type="PatternLayout"
  9. pattern="[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c{10}]%m%n" />
  10. </Appender>
  11. </Appenders>
  12. <Loggers>
  13. <!-- 可加性为false -->
  14. <Logger name="test" level="info" additivity="false">
  15. <AppenderRef ref="STDOUT" />
  16. </Logger>
  17. <!-- root loggerConfig设置 -->
  18. <Root level="info">
  19. <AppenderRef ref="STDOUT" />
  20. </Root>
  21. </Loggers>
  22. </Configuration>

4.准备好一个待统计单词个数的文本文件,如下所示:

 

2.编写代码

MapReudce的代码主要分三段:分别是map、reduce和driver,注意导包等细节

map阶段代码如下:

  1. /**
  2. * LongWritable, Text,Text, IntWritable
  3. * LongWritable : 是输入的文本
  4. * Text : 输入的一行内容
  5. * Text : 输出的一个单词
  6. * IntWritable : 输出的单词的个数
  7. */
  8. public class WCMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
  9. private Text outKey = new Text();
  10. private IntWritable outValue = new IntWritable(1);
  11. @Override
  12. protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  13. //1.将value转化为String类型的数据进行操作,并获取一行数据进行操作
  14. String line = value.toString();
  15. String[] words = line.split(" "); //将一行中的每个单词使用" "分开
  16. //2.遍历一行数据
  17. for (String word : words) {
  18. //将获取的word作为输出的key
  19. outKey.set(word);
  20. outValue.set(1);
  21. //3.将获取的每一个key和value都输出,并将其写出
  22. context.write(outKey,outValue);
  23. }
  24. }
  25. }

 这里要注意,单词使用符号进行分割,就要使用相应的符号进行切分。

reduce阶段代码如下:

  1. /**
  2. * Text map阶段输入的key类型
  3. * IntWritable map阶段输入的value类型
  4. * Text reduce阶段输出的key类型
  5. * IntWritable reduce阶段输出的value类型
  6. */
  7. public class WCReducer extends Reducer<Text, IntWritable,Text,IntWritable> {
  8. private IntWritable outValue = new IntWritable();
  9. @Override
  10. protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
  11. //统计相同key元素的个数
  12. int sum = 0;
  13. for (IntWritable value : values) {
  14. sum += value.get();
  15. }
  16. //为输出的value赋值
  17. outValue.set(sum);
  18. //将相同的key的value全部统计好才将key和value写出
  19. context.write(key,outValue);
  20. }
  21. }

 编写main方法类:

  1. public class WCDriver {
  2. public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
  3. //1.设置配置文件
  4. Configuration conf = new Configuration();
  5. //2.获取一个Job实例对象
  6. Job job = Job.getInstance();
  7. //3.为job设置一个Driver
  8. job.setJarByClass(WCDriver.class);
  9. //4.为job设置mapper和reducer
  10. job.setMapperClass(WCMapper.class);
  11. job.setReducerClass(WCReducer.class);
  12. //5.设置job的map阶段输出的key和value类型
  13. job.setMapOutputKeyClass(Text.class);
  14. job.setMapOutputValueClass(IntWritable.class);
  15. //6.设置job的reduce阶段输出的key和value类型
  16. job.setOutputKeyClass(Text.class);
  17. job.setOutputValueClass(IntWritable.class);
  18. //7.设置文件的输入路径和输出路径
  19. FileInputFormat.setInputPaths(job,new Path("D:/test/wcinput"));
  20. FileOutputFormat.setOutputPath(job,new Path("D:/test/tout"));
  21. //8.开始执行任务
  22. boolean result = job.waitForCompletion(true);
  23. System.exit(result?0:1); //0正常退出程序,1异常退出程序
  24. }
  25. }

 需要注意两点,1.若是在本地运行job.setJarByClass(WCDriver.class);可以不用写,但如果在集群上运行,上面代码不写会发生错误。2.文件的输出路径必须不能存在,否则或报错。Output directory file:/D:/test/tout already exists,可以将tout目录删除,或输入一个路径不存在的目录。

3.运行项目

经过几秒钟的运行,可以看到在file:/D/test/tout目录下生成了如下四个文件,前两个是.crc校验文件,用来校验输出的内容是否被修改 

 用编辑器打开后两个文件中的一个,看wordcount统计结果

可能会奇怪,第一行的1是什么呢,这里是因为输入的时候不小心按了两个空格,导致两个空格之间的空内容也被统计了一次。对比一下之前输入的单词,发现统计结果正确。简单的测试MapReduce程序完成。

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/337584
推荐阅读
相关标签
  

闽ICP备14008679号