版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012369535/article/details/89707273
输入数据
有以下两个输入文件a.txt和b.txt,目的是将其按照第一列进行join,输入文件如下:
利用MR进行join
思路是利用框架的排序机制,先用一个MapReduce(此时不对reduce进行任何编码,没有reduce,map处理后直接输出,作为下一个MapReduce的输入)将两个文件的数据以<key,flag,value>的形式输出(flag=1表示来自a.txt,flag=2来自b.txt),具体分别对a.txt和b.txt执行map_a.py和map_b.py,产生各自的输出文件:
[root@master mapreduce_join]# cat map_a.py
#!/bin/python
import sys
for line in sys.stdin:
ss = line.strip().split(' ')
key = ss[0]
value = ss[1]
print "%s\t1\t%s" % (key,value)
[root@master mapreduce_join]# cat map_b.py
#!/bin/python
import sys
for line in sys.stdin:
ss = line.strip().split(' ')
key = ss[0]
value = ss[1]
print "%s\t2\t%s" % (key,value)
在得到上述两个输出文件后,进入第二个MapReduce阶段,读取两个输出文件作为输入,此时的map不作任何处理便输出,输出形式仍然是<key,flag,value>,对map的输出结果指定以第一列作为partition的字段,每个partition内以前两列作为排序的字段来进行shuffle,实现两个文件中具有相同join on列(key)的数据交由同一个reduce处理,执行red_join.py:
[root@master mapreduce_join]# cat red_join.py
#!/bin/python
import sys
val_1 = ""
for line in sys.stdin:
key, flag, value = line.strip().split('\t')
if flag == '1':
val_1 = value
elif flag == '2' and val_1 != "":
val_2 = value
print"%s\t%s\t%s" % (key, val_1, val_2)
val_1 = ""
整个join的MapReduce执行流程如下:
[root@master mapreduce_join]# cat run.sh
set -e -x
HADOOP_CMD="/usr/local/src/hadoop/hadoop-2.6.5/bin/hadoop"
STREAM_JAR_PATH="/usr/local/src/hadoop/hadoop-2.6.5/share/hadoop/tools/lib/hadoop-streaming-2.6.5.jar"
INPUT_FILE_PATH_A="/a.txt"
INPUT_FILE_PATH_B="/b.txt"
OUTPUT_A_PATH="/output_a"
OUTPUT_B_PATH="/output_b"
OUTPUT_JOIN_PATH="/output_join"
#$HADOOP_CMD fs -rmr -skipTrash $OUTPUT_A_PATH $OUTPUT_B_PATH $OUTPUT_JOIN_PATH
#$HADOOP_CMD fs -rmr -skipTrash $OUTPUT_JOIN_PATH
# Step 1.
$HADOOP_CMD jar $STREAM_JAR_PATH \
-input $INPUT_FILE_PATH_A \
-output $OUTPUT_A_PATH \
-mapper "python map_a.py" \
-file ./map_a.py \
# Step 2.
$HADOOP_CMD jar $STREAM_JAR_PATH \
-input $INPUT_FILE_PATH_B \
-output $OUTPUT_B_PATH \
-mapper "python map_b.py" \
-file ./map_b.py \
# Step 3.
$HADOOP_CMD jar $STREAM_JAR_PATH \
-input $OUTPUT_A_PATH,$OUTPUT_B_PATH \
-output $OUTPUT_JOIN_PATH \
-mapper "cat" \
-reducer "python red_join.py" \
-file ./red_join.py \
-jobconf stream.num.map.output.key.fields=2 \
-jobconf num.key.fields.for.partition=1
执行结果
对a.txt和b.txt执行第一个MapReduce的输出如下(对应run.sh的step1,2),此时未指定reduce的编码,在shuffle阶段默认以第一列作为key(分区和排序都以此列)去执行shuffle阶段,然后执行框架的字典排序:
将具有相同join on列(key)的value进行连接,run.sh的step3的输出结果如下: