- 测试数据
# lixiang_list.txt(小表,可以在map端加载到内存中)
#立项ID 立项名称
1800 心愿券测试003
1801 fw心愿单
1802 wtest心愿券0524
1803 HW心愿单01
1804 心愿券测试006
1805 心愿券测试007
1806 心愿券测试008
# order_list.txt (大表)
#订单编号 用户手机号 订单金额 创建时间 立项ID 用户ID
18050411131170468193 18511745550 0.01 1525403591 1768 6502216546
18050411131741948542 18511745550 0.01 1525403597 1768 6502216546
18050411132051347006 18511745550 0.01 1525403600 1768 6502216546
18050411132624157487 18511745550 0.01 1525403606 1768 6502216546
#连接结果
立项ID 立项名称 订单编号 订单金额 用户手机号 用户ID 创建时间
思路
提交作业的时候,将小表文件(lixiang_list.txt)文件以缓存的形式上提交到HDFS上,然后在每个map中先将lixiang_list.txt中的数据加载到内存,然后根据接收到的大表的数据,判断是否需要进行连接。
实例代码:
#work.bash #! /bin/bash #定义map和reduce的目录 export WORK_PATH=/var/tmp/map_join #执行stream的jar包地址 stream=$HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-2.7.5.jar #数据输入目录 input=/lcy/map_join/input #输出结果目录 output=/lcy/map_join/output #删除mr输出目录 if $HADOOP_HOME/bin/hdfs dfs -test -d $output then $HADOOP_HOME/bin/hdfs dfs -rm -r $output fi #执行mapreduce程序 $HADOOP_HOME/bin/hadoop jar $stream \ -D mapreduce.job.reduces=3 \ -D num.key.fields.for.partition=1 \ -D stream.num.map.output.key.fields=1 \ -files $WORK_PATH/lixiang_list.txt \ -input $input/* \ -output $output \ -mapper "python mr.py mapper" \ -file $WORK_PATH/mr.py
mapreduce文件
#! /usr/bin/env python # coding:utf-8 import sys import os dct_lx = {} def read_input(file,sepr=' '): for line in file: data = line.split(sepr) yield data def read_lx_data(): global dct_lx with open('lixiang_list.txt','r') as f: for line in f: line = line.split(' ',1) dct_lx[line[0].strip()] = line[1].strip() def mapper(): global dct_lx filepath = os.environ['map_input_file'] filename = os.path.split(filepath)[1] lines = read_input(sys.stdin) for data in lines: if "order_list.txt" == filename: if len(data) != 6: continue if data[4] in dct_lx: print "%s\t%s\t%s\t%s\t%s\t%s\t%s" % (data[4],dct_lx[data[4]],data[0],data[2],data[1],data[5].strip('\n'),data[3]) if __name__ == '__main__': d = {"mapper":mapper} if sys.argv[1] in d: #加载小表数据 read_lx_data() d[sys.argv[1]]()