9.Join的应用

文章详细介绍了在HadoopMapReduce环境中如何使用reduceJoin和MapJoin来合并两个表的数据。reduceJoin通过Map阶段的数据封装和Reduce阶段的数据处理,实现了基于pid的表合并,而MapJoin则通过在map阶段完成join,避免了reduce过程,提高了效率,尤其适用于内表较小的情况。文章提供了具体的Order类实现、mapper和reducer的编写示例,以及driver类的配置说明。
摘要由CSDN通过智能技术生成

1.reduceJoin的应用

案例:将两个表合并成一个新的表

               

需求分析通过将关联条件作为Map输出的key(此处指pid),将两表满足Join条件的数据并携带数据所来源的文件信息,发往同一个ReduceTask,在Reduce中进行数据的串联

思路:

map:

将输入数据统一封装为一个Bean,此Bean包含了商品表和订单表的所有公共和非公共属性,相当于进行了全外连接,并新增加一个属性——文件名称,以区分数据是来自与商品表还是订单表,便于在reduce阶段数据的 处理;map输出的key是pid,value是bean

shuffle:

根据pid对bean进行排序,所有pid相同的数据都会被聚合到同一个key下,发往同一个reducetask

reduce:

对同一个pid下所有的bean,首先要区分出它们是来自于哪个表,是商品表还是订单表。如果是商品表,数据只有一条,保存其中的pname属性;如果是订单表,数据有多条,用保存的pname属性替换pid属性,并输出

 代码:

(1)创建表格合并后的Order类

public class OrderPd implements Writable {
    private String id; //订单id
    private String pid; //产品id
    private int amount; //产品数量
    private String pname; //产品名称
    private String flag; //判断是order表还是pd表的标志字段
}

一键生成set/get/构造函数(略过)

重写toString():

  @Override
    public String toString() {
        return id + "\t" + pname + "\t" + amount;
    }

将这五个特征序列化:

    public void write(DataOutput out) throws IOException {
        out.writeUTF(id);
        out.writeUTF(pid);
        out.writeInt(amount);
        out.writeUTF(pname);
        out.writeUTF(flag);
    }

反序列化:

    public void readFields(DataInput in) throws IOException {
        this.id = in.readUTF();
        this.pid = in.readUTF();
        this.amount = in.readInt();
        this.pname = in.readUTF();
        this.flag = in.readUTF();
    }

 (2)编写mapper类:将两个表上下拼接到了一起

 思路:先获取文件名,然后根据不同的文件名执行不同的操作

 (3)编写reducer类:将一组的数据完成join

       接受的key就是pid,value就是orderpd,输出的就只有orderpd.

思路:先找到一行中的pname,然后将来自order中的数据设置pname并输出

ps.以上的reducer类存在优化空间,因为创建临时变量的时候需要不断的new新空间,浪费大量内存,因此做出已下改进:每处理一次对象,就用之前申请的那个对象

(4)编写driver类

 2.Mapjoin的应用

定义

没有reduce过程,所有的工作都在map阶段完成,极大减少了网络传输和io的代价。如何实现:

上述的join过程可以看作外表与内表的连接过程,外表是订单表,外表大,外表是处理的对象;内表是商品表,内表小,内表是写进内存的对象。所以可以把内表事先缓存于各个maptask结点,然后等到外表的数据传输过来以后,直接用外表的数据连接内表的数据并输出即可

思路:

1)在driver中设置加载缓存文件,这样每个maptask就可以获取到该文件 ; 设置reducetask个数为0,去除reduce阶段,对应到这个需求就是遍历order表的时候,把pd表做成一个map写入缓存中方便随时调用拿到pname

2)在setup方法中读取缓存文件,并将结果以kv的形式存入hashmap,k是pid,v是pname

3)在map方法中,根据pid,通过hashmap找到pname,替换pid,写出结果

 代码

(1)mapper类

(2)driver类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值