MapReduce实现简单join(利用框架排序机制)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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的输出结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u012369535/article/details/89707273