头歌 MapReduce的编程开发-合并

头歌 MapReduce的编程开发-合并

任务描述:

本关任务:根据课程信息数据、学生信息数据与学员成绩数据,编写 MapReduce 程序来将三个数据文件合并为一个文件。

相关知识概述:

        合并是 MapReduce 最为常见的操作,将多个文件合并为一个文件或者将多个文件进行连接操作,最终返回一个文件。使用 map 端合并或者使用 reduce 端合并都是可以进行合并操作。

        使用 map 端合并,先在 setup() 方法中读取文件,循环读取文件内容并切割,将切割后的数据存入集合中,在 map 方法中获取文件内容并切割,通过切割后的数据去匹配集合中的数据,达到替换操作。

        使用 reduce 端合并,在 map 方法中读取数据,通过不同文件将数据标明 key 值传入 reduce 端,reduce 通过 key 值不同去处理数据,将需要匹配的到的数据放入集合中,需要转换的数据匹配集合中的数据,达到替换操作。这种方式中,合并的操作是在 reduce 阶段完成,reduce 端的处理压力太大,map 节点的运算负载则很低,资源利用率不高,且在reduce阶段极易产生数据倾斜。

数据文件格式说明:

        这是编程中用到的数据,为 txt 格式,文件名score.txtstudent.txtcourse.txt。 数据文件位置:/data/workspace/myshixun/data 学生信息文件student.txt前几行示例如下:

  1. 3108001,wang min,21,f,computer-tec,zhongshan road,jiangsu
  2. 3108002,jidu,20,m,english,zhongshan road,fujian
  3. 3108003,wangqing,19,f,computer-tec,zhongshan road,jiangsu
  4. 3108004,liuxin,23,f,chinese,zhongshan road,shanghai
  5. ···
  • 每一行数据(7列)分别表示: 学员id,学员名字,学员性别(m代表男,f代表女),专业名称,住址,籍贯

课程信息文件course.txt前几行示例如下:

  1. 8108001,math,sandy
  2. 8108002,english,sherry
  3. 8108003,computer,sandy
  4. 8108004,web,sandy
  5. 8108005,java,sandy
  6. ···
  • 每一行数据(3列)分别表示: 课程id, 课程称, 执教老师

学生成绩文件score.txt前几行示例如下:

  1. 3108001,8108010,90
  2. 3108001,8108003,67
  3. 3108002,8108003,54
  4. 3108002,8108010,84
  5. 3108003,8108003,78
  6. 3108004,8108004,89
  7. ···
  • 每一行数据(3列)分别表示: 学员id, 课程id, 成绩
编程要求:

        根据提示,在右侧编辑器补充代码,将课程信息数据、学生信息数据与学员成绩数据合并为一个有学员名称、课程名称、成绩三个字段的文件。

  • 本关卡不指定使用 map 端合并或 reduce 端合并。

  • main 方法已给出,其中 Job 和输入输出路径已配置完成,若用到reduce 端无需再指定 Reducer 类,若没有用到 reduce 可以注释;

  • 需设置 map 函数与 reduce 函数输出数据的key和value的类型;

预期输出格式:

  1. 学员姓名,课程名称,成绩
  2. 学员姓名,课程名称,成绩
  3. ···
  4. ···
测试说明:

        平台会对你编写的代码进行测试,如果编写的 MapReduce 输出与预期一致,则通过。

答案:

package mergeData.mapreduce;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
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;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
public class MergeDataDriver {
    /********** Begin **********/
    public static class Map extends Mapper {
         HashMap studentMap = new HashMap();
        HashMap courseMap = new HashMap();
        @Override
        protected void setup(Context context) throws IOException, InterruptedException {
            BufferedReader reader1 = new BufferedReader(new InputStreamReader(new FileInputStream("/data/workspace/myshixun/data/student.txt"),"UTF-8"));
            BufferedReader reader2 = new BufferedReader(new InputStreamReader(new FileInputStream("/data/workspace/myshixun/data/course.txt"),"UTF-8"));
            String line1;
            String line2;
            while(StringUtils.isNotEmpty(line1 = reader1.readLine())){
                // 2 切割
                String[] fields = line1.split(",");
                // 3 缓存数据到集合
                studentMap.put(fields[0], fields[1]);
            }
            while(StringUtils.isNotEmpty(line2 = reader2.readLine())){
                // 2 切割
                String[] fields = line2.split(",");
                // 3 缓存数据到集合
                courseMap.put(fields[0], fields[1]);
            }
        }
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            //获取输入的行
            String line=value.toString();
            //取出无效记录
            if (line == null || line.equals("")){
                return ;
            }
            //以 , 分割成字符串列表
            String[] values = line.split(",");
            String studentname="";
            String coursename="";
            if(studentMap.containsKey(values[0])){
                studentname=studentMap.get(values[0]);
            }
            if (courseMap.containsKey(values[1])){
                coursename=courseMap.get(values[1]);
            }
            values[0]=studentname;
            values[1]=coursename;
            String result="";
            int n=0;
            for (String score:values){
                if (n==values.length-1){
                    result+=score;
                }else{
                    result+=score+",";
                }
                n++;
            }
            context.write(NullWritable.get(),new Text(result));
        }
        /********** End **********/
    }
    public static class  Reduce extends Reducer{
        /********** Begin **********/
        /********** End **********/
    }
    public static void main(String[] args) throws  Exception {
        //创建配置信息
        Configuration conf = new Configuration();
        // 创建任务
        Job job = Job.getInstance(conf);
        //如果输出目录存在,我们就删除
        String outputpath = "/root/files";
        Path path = new Path(outputpath);
        FileSystem fileSystem = path.getFileSystem(conf);
        if (fileSystem.exists(path)) {
            fileSystem.delete(path, true);
        }
        /********** Begin **********/
        //设置执行类
        job.setJarByClass(MergeDataDriver.class);
        //设置自定义Mapper类
        job.setMapperClass(Map.class);
        //设置自定义Reducer类(若没用reduce可删除)
        //job.setReducerClass(Reduce.class);
        //设置map函数输出数据的key和value的类型
        job.setMapOutputKeyClass(NullWritable.class);
        job.setMapOutputValueClass(Text.class); 
        //设置输入输出路径
        FileInputFormat.addInputPath(job, new Path("/data/workspace/myshixun/data/score.txt"));
        FileOutputFormat.setOutputPath(job, path);
        /********** End **********/
        //提交作业,若成功返回true,失败返回falase
        boolean b = job.waitForCompletion(true);
        if (b) {
            System.out.println("恭喜,清洗成功");
        } else {
            System.out.println("不好意思,清洗失败");
        }
    }
}

创作不易,如果能解决您的问题,麻烦您点赞、收藏+关注,一键三连!!!

你可能感兴趣的:(头歌,mapreduce,大数据)