【李老师云盘算】作业二:参照Eclipse Mapreduc访问Hadoop文档,求解n个数 ...

打印 上一主题 下一主题

主题 912|帖子 912|积分 2736

3.2 作业配置实现(评分点7)编写main函数,辅以充分的注释
3.3 Map过程的实现(评分点8)Mapper类的局部变量、编写map函数,辅以充分的注释
3.4 Reduce过程的实现(评分点9)Reducer类的局部变量、编写reduce函数,辅以充分的注释
4. 测试(评分点10)给出测试数据,运行程序,得出盘算效果。
参考答案:

1.1 MapReduce编程模型
MapReduce编程模型是一种分布式盘算框架,其核心思想是将大规模数据集划分为许多小数据块,然后将这些小数据块分别交给多个盘算节点进行处理,最终将效果进行合并。MapReduce编程模型包罗两个阶段:Map阶段和Reduce阶段。在Map阶段,每个盘算节点都会对自己所负责的数据块进行处理,将其映射为一系列键值对。在Reduce阶段,这些键值对会被按照键进行合并,并进行聚合利用。
1.2 MapReduce处理过程
MapReduce处理过程包括以下几个步骤:

  • 输入分片:将输入数据分割为若干个数据块。
  • Map处理:对每个数据块进行Map处理,并将效果输出为若干个键值对。
  • Shuffle过程:对Map输出的键值对进行合并、排序、分组等利用,将同一键的值合并在一起,天生若干个键值对集合。
  • Reduce处理:对每个键值对集合进行Reduce处理,天生若干个输出键值对。
  • 输出:将Reduce输出的效果生存到输出文件中。
  • MapReduce求最大值处理过程
2.1 分割过程
在这个问题中,我们需要将输入数据分割为若干个数据块,每个数据块包罗若干个数值。由于我们需要求的是最大值,因此我们可以将数据块分割为大小相等的若干个子数据块,每个子数据块的大小为m。例如,如果输入数据为[1, 3, 5, 2, 4, 6, 7, 9, 8, 10],而且m=3,则我们可以将数据块分割为三个子数据块:[1, 3, 5], [2, 4, 6], [7, 9, 8, 10]。
2.2 Map排序与Combine过程
在Map阶段,每个盘算节点都会对自己所负责的数据块进行处理,将其映射为一系列键值对。由于我们需要求最大值,因此我们可以将每个数据块中的最大值作为键,将输入数据块的编号作为值。例如,对于子数据块[1, 3, 5],其最大值为5,编号为0,因此我们可以将键值对(5, 0)输出。
在Map阶段的输出效果需要进行合并利用,以淘汰Reduce阶段的数据量。在本问题中,我们可以将Map输出的键值对按照键进行排序,并将同一键的值进行合并,天生若干个键值对集合。由于我们的键是数值,因此我们需要对键进行升序排序。
在对键值对进行排序的过程中,可以通过自定义比较器来指定排序方式。对于本问题中的键值对,我们可以通过编写一个比较器类来指定按照键的升序排序。下面是一个示例代码:
  1. public class MaxValueComparator extends WritableComparator {
  2.     protected MaxValueComparator() {
  3.         super(IntWritable.class, true);
  4.     }
  5.     @Override
  6.     public int compare(WritableComparable a, WritableComparable b) {
  7.         IntWritable int1 = (IntWritable) a;
  8.         IntWritable int2 = (IntWritable) b;
  9.         return int1.compareTo(int2);
  10.     }
  11. }
复制代码
在Map阶段的输出效果进行合并利用时,可以通过Combine过程来进一步淘汰数据量。Combine过程与Reduce过程相似,但是其运行在Map节点上,而且可以在Map节点上进行合并利用。在本问题中,我们可以使用Reduce过程作为Combine过程,将同一键的值进行合并,并输出合并后的键值对集合。
2.3 Reduce排序与输出效果
在Reduce阶段,对于每个键值对集合,我们可以对其进行Reduce利用,求出最大值。例如,对于键值对集合(5, [0, 2]),我们可以求出其对应的最大值10。对于本问题中的Reduce利用,我们可以编写一个Reducer类来实现。下面是一个示例代码:
  1. public class MaxValueReducer extends Reducer<IntWritable, IntWritable, IntWritable, IntWritable> {
  2.     private IntWritable result = new IntWritable();
  3.     @Override
  4.     public void reduce(IntWritable key, Iterable<IntWritable> values, Context context)
  5.             throws IOException, InterruptedException {
  6.         int max = Integer.MIN_VALUE;
  7.         for (IntWritable value : values) {
  8.             max = Math.max(max, value.get());
  9.         }
  10.         result.set(max);
  11.         context.write(key, result);
  12.     }
  13. }
复制代码
在Reduce阶段的输出效果需要进行排序利用,以便将最大值排在最前面。在本问题中,我们可以使用与Map阶段雷同的方式对输出效果进行排序,即使用一个比较器类来指定按照键的升序排序。下面是一个示例代码:
  1. job.setSortComparatorClass(MaxValueComparator.class);
复制代码

  • 基于Eclipse的MapReduce项目求解最大值
3.1 Eclipse访问HDFS
在基于Eclipse的MapReduce项目中,我们需要使用HDFS作为输入和输出的数据源。因此,在编写代码之前,我们需要确保Hadoop和HDFS已经安装并运行在本地环境中。在Eclipse中,可以通过添加Hadoop库来访问HDFS。下面是一个示例代码:
  1. Configuration conf = new Configuration();
  2. conf.set("fs.defaultFS", "hdfs://localhost:9000");
  3. FileSystem fs = FileSystem.get(conf);
  4. Path inputPath = new Path("/input");
  5. Path outputPath = new Path("/output");
  6. if (fs.exists(outputPath)) {
  7.     fs.delete(outputPath, true);
  8. }
复制代码
3.2 作业配置实现
在配置MapReduce作业时,我们需要指定作业的输入、输出、Mapper类、Reducer类等信息。
  1. Job job = Job.getInstance(conf, "max value");
  2. job.setJarByClass(MaxValue.class);
  3. job.setMapperClass(MaxValueMapper.class);
  4. job.setCombinerClass(MaxValueReducer.class);
  5. job.setReducerClass(MaxValueReducer.class);
  6. job.setOutputKeyClass(IntWritable.class);
  7. job.setOutputValueClass(IntWritable.class);
  8. FileInputFormat.addInputPath(job, inputPath);
  9. FileOutputFormat.setOutputPath(job, outputPath);
复制代码
在配置作业时,我们需要通过Job类的getInstance方法来获取一个作业实例,并指定作业的名称和运行配置。在本问题中,我们可以指定作业名称为"max value"。通过setJarByClass方法来指定运行作业的类,即MaxValue类。通过setMapperClass、setCombinerClass和setReducerClass方法来指定Mapper、Combine和Reducer类。通过setOutputKeyClass和setOutputValueClass方法来指定输出键和值的类型。最后,通过FileInputFormat和FileOutputFormat类的addInputPath和setOutputPath方法来指定作业的输入和输出路径。
  1. public class MaxValue {
  2.     public static void main(String[] args) throws Exception {
  3.         Configuration conf = new Configuration();
  4.         conf.set("fs.defaultFS", "hdfs://localhost:9000");
  5.         FileSystem fs = FileSystem.get(conf);
  6.         Path inputPath = new Path("/input");
  7.         Path outputPath = new Path("/output");
  8.         if (fs.exists(outputPath)) {
  9.             fs.delete(outputPath, true);
  10.         }
  11.         Job job = Job.getInstance(conf, "max value");
  12.         job.setJarByClass(MaxValue.class);
  13.         job.setMapperClass(MaxValueMapper.class);
  14.         job.setCombinerClass(MaxValueReducer.class);
  15.         job.setReducerClass(MaxValueReducer.class);
  16.         job.setOutputKeyClass(IntWritable.class);
  17.         job.setOutputValueClass(IntWritable.class);
  18.         FileInputFormat.addInputPath(job, inputPath);
  19.         FileOutputFormat.setOutputPath(job, outputPath);
  20.         boolean success = job.waitForCompletion(true);
  21.         if (success) {
  22.             System.out.println("Job completed successfully.");
  23.         }
  24.     }
  25. }
复制代码
在main函数中,我们起首创建一个Configuration对象,并设置默认文件系统为本地HDFS。然后,我们获取一个FileSystem对象,并指定输入和输出路径。在作业配置之后,我们通过调用waitForCompletion方法来等待作业运行完毕。最后,我们输出作业运行效果。如果作业运行成功,输出"Job completed successfully."。
3.3 Map过程的实现
  1. public class MaxValueMapper extends Mapper<LongWritable, Text, IntWritable, IntWritable> {
  2.     private final IntWritable one = new IntWritable(1);
  3.     private IntWritable number = new IntWritable();
  4.     @Override
  5.     public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  6.         String[] numbers = value.toString().split(",");
  7.         for (String s : numbers) {
  8.             number.set(Integer.parseInt(s));
  9.             context.write(one, number);
  10.         }
  11.     }
  12. }
复制代码
在Mapper类中,我们起首声明两个局部变量:一个IntWritable类型的one变量,用于作为键;一个IntWritable类型的number变量,用于作为值。在map函数中,我们起首将输入的一行文本转换为一个字符串数组,然后遍历该数组。对于数组中的每个元素,我们将其转换为一个整数,并将其赋值给number变量。接下来,我们将one作为键,number作为值,通过调用Context对象的write方法写入上下文。如许,Map函数就将每个输入数值作为值输出,而将固定的键1与每个数值组合。
在Reducer类中,我们同样起首声明一个局部变量,用于生存输入值的最大值。在reduce函数中,对于每个键值对,我们将值转换为一个整数,并与当前最大值进行比较。如果值大于当前最大值,则将该值赋值给最大值变量。最后,我们通过调用Context对象的write方法将最大值写入上下文。
  1. public static class MaxReducer extends Reducer<IntWritable, IntWritable, IntWritable, IntWritable> {
  2.     private IntWritable result = new IntWritable();
  3.     public void reduce(IntWritable key, Iterable<IntWritable> values, Context context)
  4.             throws IOException, InterruptedException {
  5.         int max = Integer.MIN_VALUE;
  6.         for (IntWritable val : values) {
  7.             max = Math.max(max, val.get());
  8.         }
  9.         result.set(max);
  10.         context.write(key, result);
  11.     }
  12. }
复制代码
完整的代码如下:
  1. import java.io.IOException;
  2. import org.apache.hadoop.conf.Configuration;
  3. import org.apache.hadoop.fs.Path;
  4. import org.apache.hadoop.io.LongWritable;
  5. import org.apache.hadoop.io.Text;
  6. import org.apache.hadoop.mapreduce.Job;
  7. import org.apache.hadoop.mapreduce.Mapper;
  8. import org.apache.hadoop.mapreduce.Reducer;
  9. import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
  10. import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
  11. public class MaxValue {
  12.     public static class MaxValueMapper extends Mapper<LongWritable, Text, LongWritable, LongWritable> {
  13. ![](https://img-blog.csdnimg.cn/img_convert/9a8cb5f8c0ec69e6499adead0da6e95b.png)
  14. 最全的Linux教程,Linux从入门到精通
  15. ======================
  16. 1.  **linux从入门到精通(第2版)**
  17. 2.  **Linux系统移植**
  18. 3.  **Linux驱动开发入门与实战**
  19. 4.  **LINUX 系统移植 第2版**
  20. 5.  **Linux开源网络全栈详解 从DPDK到OpenFlow**
  21. ![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/59742364bb1338737fe2d315a9e2ec54.png)
  22. 第一份《Linux从入门到精通》466页
  23. ====================
  24. 内容简介
  25. ====
  26. 本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。
  27. ![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)
  28. **本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**
  29. > 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论
  30. **网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
  31. **[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618542503)**
  32. **一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表