适用场景:一张表十分小【key不可重复】、一张表非常大。
用法:在Job提交时,首先将小表加载到 DistributedCache 分布式缓存中,然后从DistributeCache中读取小表解析成 key/value 保存到内存中(可以放在Hash Map等容器中)。然后扫描大表中的每条记录的 key 是否能在内存中找到相同 join key 的记录,如果有则直接输出结果。

package join.map;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap; 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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /**
* map-join中小表的数据如下:
*
* 1 Beijing
* 2 Guangzhou
* 3 Shenzhen
* 4 Xian
*
* 大表的数据如下:
*
* Beijing Red Star 1
* Shenzhen Thunder 3
* Guangzhou Honda 2
* Beijing Rising 1
* Guangzhou Development Bank 2
* Tencent 3
* Back of Beijing 1
*/
public class MapJoin { public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
job.setJarByClass(MapJoin2.class);

//此方法已过时,被job.addCacheFile()所取代
//DistributedCache.addCacheFile(new URI("hdfs://10.16.17.182:9000/test/in/address.txt"), conf);

//加载小表到 分布式缓存DistributedCache
     job.addCacheFile(new Path(args[0]).toUri());

job.setMapperClass(MJMapper.class);
job.setNumReduceTasks(0);

job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);

job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);

FileInputFormat.addInputPath(job, new Path(args[1]));
FileOutputFormat.setOutputPath(job, new Path(args[2]));

System.exit(job.waitForCompletion(true)? 0:1);
} public static class MJMapper extends Mapper<LongWritable, Text, Text, Text>{ /**
* 此map是存放小表数据用的
* 注意小表的key是不能重复的,类似与数据库的外键表
* 在这里的小表,就相当于一个外键表
* **/
private HashMap<String, String> map=new HashMap<String, String>(); @Override
protected void setup(Context context) throws IOException, InterruptedException { BufferedReader br=null; // 读取文件流
String line; // 获取DistributedCached里面 的共享文件
        Path[] paths = context.getLocalCacheFiles(); for(Path path : paths){
if(path.getName().indexOf("address") >= 0){ //如果是 address文件
            br=new BufferedReader(new FileReader(path.toString())); while((line=br.readLine()) != null){ //读取文件中的每一行
               String[] splited = line.split("\t"); map.put(splited[0], splited[1]); //将小表解析成 key/value 存放进map
}
}
}
} /**
* map阶段读取并处理大表中的数据
* 小表中的数据是加载到HashMap中的,无需从hdfs读取
*/
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException { if(value==null || ("").equals(value.toString())){ //跳过空值
return;
} String[] splited = value.toString().split("\t");

if(map.get(splited[1]) != null){ //map中大表的 key 对应的 value 不为空

Text keyOut = new Text(splited[0]); //key=大表的第一列
Text valueOut = new Text(map.get(splited[1])); //value=小表的第二列

context.write(keyOut, valueOut);
}
}
}
}

更多参考分布式缓存DistributedCache

MR案例:Map-Join的更多相关文章

  1. MR案例:Reduce-Join

    问题描述:两种类型输入文件:address(地址)和company(公司)进行一对多的关联查询,得到地址名(例如:Beijing)与公司名(例如:Beijing JD.Beijing Red Star ...

  2. MR案例:倒排索引

    1.map阶段:将单词和URI组成Key值(如“MapReduce :1.txt”),将词频作为value. 利用MR框架自带的Map端排序,将同一文档的相同单词的词频组成列表,传递给Combine过 ...

  3. MR案例:小文件处理方案

    HDFS被设计来存储大文件,而有时候会有大量的小文件生成,造成NameNode资源的浪费,同时也影响MapReduce的处理效率.有哪些方案可以合并这些小文件,或者提高处理小文件的效率呢? 1). 所 ...

  4. Hive 的 map join

    学习自 http://blog.csdn.net/xqy1522/article/details/6699740 1. Map Join 的使用场景: 关联操作中有一张表非常小 不等值的链接操作 2. ...

  5. HIVE: Map Join Vs Common Join, and SMB

    HIVE  Map Join is nothing but the extended version of Hash Join of SQL Server - just extending Hash ...

  6. 使用Spark进行搜狗日志分析实例——map join的使用

    map join相对reduce join来说,可以减少在shuff阶段的网络传输,从而提高效率,所以大表与小表关联时,尽量将小表数据先用广播变量导入内存,后面各个executor都可以直接使用 pa ...

  7. MapReduce编程之Map Join多种应用场景与使用

    Map Join 实现方式一:分布式缓存 ● 使用场景:一张表十分小.一张表很大. ● 用法: 在提交作业的时候先将小表文件放到该作业的DistributedCache中,然后从DistributeC ...

  8. MapReduce之Map Join

    一 介绍 之所以存在Reduce Join,是因为在map阶段不能获取所有需要的join字段,即:同一个key对应的字段可能位于不同map中.Reduce side join是非常低效的,因为shuf ...

  9. MR案例:CombineFileInputFormat

    CombineFileInputFormat是一个抽象类.Hadoop提供了两个实现类CombineTextInputFormat和CombineSequenceFileInputFormat. 此案 ...

  10. MR案例:倒排索引 && MultipleInputs

    本案例采用 MultipleInputs类 实现多路径输入的倒排索引.解读:MR多路径输入 package test0820; import java.io.IOException; import j ...

随机推荐

  1. HDU4291—A Short problem

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4291 题目意思:求g(g(g(n))) mod 109 + 7,其中g(n) = 3g(n - 1) ...

  2. 给Django后台富文本编辑器添加上传文件的功能

    使用富文本编辑器上传的文件是要放到服务器上的,所以这是一个request.既然是一个request,就需要urls.py进行转发请求views.py进行处理.views.py处理完了返回一个文件所在的 ...

  3. Linux命令(基础3)

    关机重启 reboot poweroff ============================ linux命令分类 1.针对不同文件的管理命令 1.1 目录 FHS 文件系统层次化标准 绝对路径: ...

  4. PageHelper中默认PageInfo成员变量

    以下是PageHelper中默认PageInfo的成员变量,方便以后自己使用 //当前页 private int pageNum; //每页的数量 private int pageSize; //当前 ...

  5. SDUT3145:Integer division 1(换零钱背包)

    题目:传送门 题目描述 整数划分是一个非常经典的数学问题. 所谓整数划分,是指把一个正整数n写成为n=m1+m2+...+mi的形式,其中mi为正整数,并且1<=mi<=n,此时,{m1, ...

  6. Oracle trigger 触发器

    触发器使用教程和命名规范 目  录触发器使用教程和命名规范 11,触发器简介 12,触发器示例 23,触发器语法和功能 34,例一:行级触发器之一 45,例二:行级触发器之二 46,例三:INSTEA ...

  7. 通过交换a,b 中的元素,使[序列a 元素的和]与[序列b 元素的和]之间的差最小

    题目描述: 有两个序列a,b,大小都为n,序列元素的值任意整数,无序:要求:通过交换a,b 中的元素,使[序列a 元素的和]与[序列b 元素的和]之间的差最小.例如:var a=[100,99,98, ...

  8. python3 对excel读、写、修改的操作

    一.对excel的写操作实例: 将一个列表的数据写入excel, 第一行是标题,下面行数具体的数据 import xlwt #只能写不能读 stus = [['姓名', '年龄', '性别', '分数 ...

  9. IOS开发如何入门

    说到 iOS 开发,自己学得也很浅.不过至少独立一人完成了一个应用的开发到项目上线整个过程.分享一下自己的建议和想法. 首先建议阅读 Start Developing iOS Apps Today,你 ...

  10. u-boot.cfg转eclipse_xml小脚本

    手动复制粘贴版本 cat u-boot.cfg | awk '{if(length($3)){$3 = substr($0, length($1)+length($2)+3); gsub(" ...