MapReduce案例八:MapperJoin

一、数据样例

  • 订单数据 order.txt:(订单id,商品id,销售数量)
1001    01    1
1002    02    2
1003    03    3
1004    01    4
1005    02    5
1006    03    6
  • 商品数据 pd.txt:(商品id,商品名称)
01    小米
02    华为
03    格力

二、需求

  • 将商品信息表中数据根据商品id合并到订单数据表中。

三、分析

  • 可以将小表分发到所有的map节点,这样,map节点就可以在本地对自己所读到的大表数据进行合并并输出最终结果,可以大大提高合并操作的并发度,加快处理速度。

  • 使得最终数据样例如下格式:

1005	01	1	小米
1004	02	7	华为
1003	03	3	格力
1002	01	9	小米

四、代码实现

  • 1、读取缓存的文件数据,创建 DistributedCacheMapper :
package test;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class DistributedCacheMapper extends Mapper<LongWritable, Text, Text, NullWritable>{

    Map<String, String> pdMap = new HashMap<>();
    
    @Override
    protected void setup(Mapper<LongWritable, Text, Text, NullWritable>.Context context)
            throws IOException, InterruptedException {
        // 1 获取缓存的文件
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("pd.txt"),"UTF-8"));
        
        String line;
        while(StringUtils.isNotEmpty(line = reader.readLine())){
            // 2 切割
            String[] fields = line.split("\t");
            
            // 3 缓存数据到集合
            pdMap.put(fields[0], fields[1]);
        }
        
        // 4 关流
        reader.close();
    }
    
    Text k = new Text();
    
    @Override
    protected void map(LongWritable key, Text value, Context context)
            throws IOException, InterruptedException {
        // 1 获取一行
        String line = value.toString();
        
        // 2 截取
        String[] fields = line.split("\t");
        
        // 3 获取产品id
        String pId = fields[1];
        
        // 4 获取商品名称
        String pdName = pdMap.get(pId);
        
        // 5 拼接
        k.set(line + "\t"+ pdName);
        
        // 6 写出
        context.write(k, NullWritable.get());
    }
}

  • 2、在驱动模块中添加缓存文件,创建 DistributedCacheDriver :
package test;

import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class DistributedCacheDriver {

    public static void main(String[] args) throws Exception {

        args = new String[]{"D:\\大数据API\\datas", "D:\\大数据API\\dataout"};

        // 1 获取job信息
        Configuration configuration = new Configuration();
        Job job = Job.getInstance(configuration);

        // 2 设置加载jar包路径
        job.setJarByClass(DistributedCacheDriver.class);

        // 3 关联map
        job.setMapperClass(DistributedCacheMapper.class);
        
        // 4 设置最终输出数据类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(NullWritable.class);

        // 5 设置输入输出路径
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        // 6 加载缓存数据
        job.addCacheFile(new URI("file:///D:/大数据API/pd.txt"));
        
        // 7 map端join的逻辑不需要reduce阶段,设置reducetask数量为0
        job.setNumReduceTasks(0);

        // 8 提交
        boolean result = job.waitForCompletion(true);
        System.exit(result ? 0 : 1);
    }
}



posted @ 2020-02-11 17:53  落花桂  阅读(455)  评论(0编辑  收藏  举报
返回顶端
Live2D