大数据-Hadoop-MapReduce-Join流程
MapReduce 计算流程
对于MapReduce的Group by - count流程大家都比较熟悉,Map阶段分组,Reduce阶段排序,但是Join操作时具体怎么样的流程我们知道的相对较少。
本文主要介绍Join 操作、 Left join操作等的流程,并且举一些数据样例做展示。
内连接Join
MapReduce是一种用于大规模数据集处理的编程模型,它包括两个阶段:Map阶段和Reduce阶段。在Map阶段,输入数据被分割成多个独立的数据块,然后每个数据块被独立地处理并生成中间输出结果。在Reduce阶段,所有的中间输出结果被聚合成最终的输出结果。
在MapReduce中执行两张表的join操作可以通过以下步骤完成:
- Map阶段:Map阶段的任务是处理输入数据并产生一些中间结果。在这个阶段,每一行输入数据都会被处理。对于join操作,Map函数会读取两个输入表的所有行,并为每一行生成一个键值对。键是join列的值,值是该行的其余部分。同时,为了区分来自不同表的数据,通常会在值中包含一些元数据,例如表的标识符。
- Shuffle阶段:在Map阶段结束后,MapReduce框架会自动将所有具有相同键的键值对发送到同一个Reduce任务。这个过程被称为Shuffle。在这个过程中,所有的键值对都会被按键排序,然后被发送到适当的Reduce任务。
- Reduce阶段:在Reduce阶段,每个Reduce任务会接收到一组具有相同键的键值对。对于join操作,Reduce函数会接收到所有具有相同join列值的行,并将它们组合在一起。Reduce函数会遍历这些行,并根据元数据将它们分配到正确的输出行。
这是一个简单的例子:
假设我们有两个表,一个是用户表(User),另一个是订单表(Order),我们想要根据用户ID进行join操作。
- User表:
UserID | UserName |
---|---|
1 | Alice |
2 | Bob |
- Order表:
OrderID | UserID | Product |
---|---|---|
1 | 1 | Apple |
2 | 2 | Banana |
3 | 1 | Cherry |
首先,Map函数会处理这两个表的所有行,并生成以下的键值对:
- User表的键值对:{(1, (User, Alice)), (2, (User, Bob))}
- Order表的键值对:{(1, (Order, 1, Apple)), (2, (Order, 2, Banana)), (1, (Order, 3, Cherry))}
然后,MapReduce框架会将所有具有相同键的键值对发送到同一个Reduce任务。在这个例子中,Reduce任务会接收到以下的键值对:
- 键为1的键值对:{(1, (User, Alice)), (1, (Order, 1, Apple)), (1, (Order, 3, Cherry))}
- 键为2的键值对:{(2, (User, Bob)), (2, (Order, 2, Banana))}
最后,Reduce函数会处理这些键值对,并生成join后的结果:
- 键为1的结果:{(1, Alice, 1, Apple), (1, Alice, 3, Cherry)}
- 键为2的结果:{(2, Bob, 2, Banana)}
这就是在MapReduce中执行两张表的join操作的基本过程。请注意,这只是一个简单的例子,实际的过程可能会更复杂,例如需要处理数据分布不均或者数据倾斜的问题。
左连接 left join
在MapReduce中执行左连接(Left Join)操作也可以,我们还是使用上述的用户表(User)和订单表(Order)的例子,但这次我们将执行左连接操作,也就是说,我们需要保留User表中的所有行,即使它们在Order表中没有匹配的行。
- User表:
UserID | UserName |
---|---|
1 | Alice |
2 | Bob |
3 | Charlie |
- Order表:
OrderID | UserID | Product |
---|---|---|
1 | 1 | Apple |
2 | 2 | Banana |
3 | 1 | Cherry |
首先,Map函数会处理这两个表的所有行,并生成以下的键值对:
- User表的键值对:{(1, (User, Alice)), (2, (User, Bob)), (3, (User, Charlie))}
- Order表的键值对:{(1, (Order, 1, Apple)), (2, (Order, 2, Banana)), (1, (Order, 3, Cherry))}
然后,MapReduce框架会将所有具有相同键的键值对发送到同一个Reduce任务。在这个例子中,Reduce任务会接收到以下的键值对:
- 键为1的键值对:{(1, (User, Alice)), (1, (Order, 1, Apple)), (1, (Order, 3, Cherry))}
- 键为2的键值对:{(2, (User, Bob)), (2, (Order, 2, Banana))}
- 键为3的键值对:{(3, (User, Charlie))}
最后,Reduce函数会处理这些键值对,并生成左连接后的结果:
- 键为1的结果:{(1, Alice, 1, Apple), (1, Alice, 3, Cherry)}
- 键为2的结果:{(2, Bob, 2, Banana)}
- 键为3的结果:{(3, Charlie, NULL, NULL)}
这就是在MapReduce中执行左连接操作的基本过程。你可以看到,即使Charlie在Order表中没有匹配的行,他仍然出现在了结果中,这就是左连接的特点。
感受
常见的教程一般以排序为例讲述mapreduce的工作机理,但是其实写sql时更常见的是使用join操作
所以了解join的作用机理对我们很有帮助