1. Reduce Join
1.1. 工作原理
Map端的主要工作:为来自不同表(文件)的key/value对打标签以区别不同来源的记录。然后用连接字段(两张表中相同的列)作为key,其余部分和新加的标志作为value,最后进行输出。
Reduce端的主要工作:在reduce端以连接字段作为key的分组已经完成,我们只需要在每一个分组当中将那些来源于不同文件的记录(在map阶段已经打标志)分开,最后进行合并就ok了
1.2. Reduce Join 案例
1.2.1. 数据说明
订单数据表 order.txt
| 订单oid | 产品pid | 产品数量amount |
|---|---|---|
| 1001 | 01 | 1 |
1 | 1001 01 1 |
商品信息表 product.txt
| 产品pid | 产品名称pname |
|---|---|
| 01 | 小米 |
1 | 01 小米 |
输出要求:将商品信息表中数据根据商品pid合并到订单数据表中
| 订单oid | 产品名称pname | 数量amount |
|---|---|---|
| 1001 | 小米 | 1 |
| 1004 | 小米 | 4 |
| 1002 | 华为 | 2 |
| 1005 | 华为 | 5 |
| 1003 | 格力 | 3 |
| 1006 | 格力 | 6 |
1.2.2. 编程程序
1.2.2.1. TableBean
1 | package mr.join; |
1.2.2.2. 编写MapReduce
1 | package mr.join; |
1.2.3. 运行
将两张表数据上传到同一目录下1
hdfs dfs -put order.txt product.txt /input
运行1
hadoop jar join.jar mr.join.JoinDriver /input /output
查看结果
1 | $ hdfs dfs -cat /output/part* |
2. Map Join
2.1. Reduce Join的缺点
Reduce Join合并操作是在Reduce阶段完成。在Reduce端处理过多的表,非常容易产生数据倾斜。
一般来説,ReduceTask数量要少于MapTask数量,Reduce端计算压力大,计算能尽量在Map阶段完成,就不在Reduce阶段做。
Reduce Join无疑给Reduce带来更大的工作量,所以推荐在Map端实现数据的合并
2.2. 适用场景
Map Join适用于一张表十分小(能直接将整张表读入内存),另一张表十分大(内存放不下)的场景
2.3. 编写程序
1 | package mr.join; |
2.4. 运行
1 | mv product.txt /root |
查看结果1
2
3
4
5
6
7$ hdfs dfs -cat /output/part*
1001 小米 1
1002 华为 2
1003 格力 3
1004 小米 4
1005 华为 5
1006 格力 6