package duogemap;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class JoinJob {

public static final String DELIMITER = "\u0009";

public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
//多路径判断
if (args.length < 2) {
System.out.println("参数数量不对,至少两个以上参数:<数据文件输出路径>、<输入路径...>");
System.exit(1);
}
//输出结果路径
String dataOutput = args[0];
//多个路输入径
String[] inputs = new String[args.length - 1];
System.arraycopy(args, 1, inputs, 0, inputs.length);

Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "join 测试");
job.setJarByClass(JoinJob.class);
job.setMapperClass(MyMapper.class);
job.setReducerClass(MyReducer.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);

//将输出路径和输入路径放入Path中
Path[] inputPathes = new Path[inputs.length];
for (int i = 0; i < inputs.length; i++) {
inputPathes[i] = new Path(inputs[i]);
}
Path outputPath = new Path(dataOutput);
FileInputFormat.setInputPaths(job, inputPathes);
FileOutputFormat.setOutputPath(job, outputPath);
job.waitForCompletion(true);
}

static class MyMapper extends Mapper<LongWritable, Text, Text, Text> {
private String inputPath;
private String fileCode = "";

protected void setup(Context context) throws IOException, InterruptedException {
// 每个文件传进来时获得文件中属性前缀
FileSplit input = (FileSplit) context.getInputSplit();
inputPath = input.getPath().getName();
try {
//获得文件名
fileCode = inputPath.split("_")[0];
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] values = value.toString().split(DELIMITER);
StringBuffer sb = new StringBuffer();
//将文件名拼接到value中,做reduce的判断标识
sb.append(fileCode + "#");
boolean first = true;
for (String v : values) {
if (!first) {
sb.append(v + DELIMITER);
}
first = false;
}
context.write(new Text(values[0]), new Text(sb.toString().substring(0, sb.toString().length() - 1)));

}
}

static class MyReducer extends Reducer<Text, Text, Text, Text> {
@Override
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
List<String> left = new ArrayList<String>();
List<String> right = new ArrayList<String>();
for (Text value : values) {
String[] vv = value.toString().split("#");
String fileCode = vv[0];
if (fileCode.equals("A.txt")) {
// 左表数据
left.add(vv[1]);
} else {
// 右表数据
right.add(vv[1]);
}
}

//只有当left和right都有数据是才会遍历
for (String l : left) {
for (String r : right) {
context.write(new Text(key), new Text(l + DELIMITER + r));
}
}
}
}
}
//首先准备数据:
//
//假设我们有2张表:
//
//表A(左表)数据:
//
//1 a
//2 b
//3 c
//3 d
//4 e
//6 f
//表B(右表)数据:
//1 10
//2 20
//3 30
//4 40
//4 400
//5 50
//我们需要得到的结果是:
//1 a 10
//2 b 20
//3 c 30
//3 d 30
//4 e 40
//4 e 400

mapreduce中一个map多个输入路径的更多相关文章

  1. Hadoop框架下MapReduce中的map个数如何控制

    控制map个数的核心源码 long minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job)); //getFormatMinS ...

  2. MapReduce中的map个数

    在map阶段读取数据前,FileInputFormat会将输入文件分割成split.split的个数决定了map的个数.影响map个数(split个数)的主要因素有: 1) 文件的大小.当块(dfs. ...

  3. MapReduce 中的Map后,sort不能对中文的key排序

    今天写了一个用mapreduce求平均分的程序,结果是出来了,可是没有按照“学生名字”进行排序,如果是英文名字的话,结果是排好序的. 代码如下: package com.pro.bq; import ...

  4. java中一个Map要找到值Value最小的那个元素的方法

    import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map ...

  5. 【Hadoop】三句话告诉你 mapreduce 中MAP进程的数量怎么控制?

    1.果断先上结论 1.如果想增加map个数,则设置mapred.map.tasks 为一个较大的值. 2.如果想减小map个数,则设置mapred.min.split.size 为一个较大的值. 3. ...

  6. MapReduce中combine、partition、shuffle的作用是什么

    http://www.aboutyun.com/thread-8927-1-1.html Mapreduce在hadoop中是一个比較难以的概念.以下须要用心看,然后自己就能总结出来了. 概括: co ...

  7. mapreduce 中 map数量与文件大小的关系

    学习mapreduce过程中, map第一个阶段是从hdfs 中获取文件的并进行切片,我自己在好奇map的启动的数量和文件的大小有什么关系,进过学习得知map的数量和文件切片的数量有关系,那文件的大小 ...

  8. 求一个Map中最大的value值,同时列出键,值

    求一个Map中最大的value值,同时列出键,值 方法1. public static void main(String[] args){  Map map=new HashMap();  map.p ...

  9. 信1705-2 软工作业最大重复词查询思路: (1)将文章(一个字符串存储)按空格进行拆分(split)后,存储到一个字符串(单词)数组中。 (2)定义一个Map,key是字符串类型,保存单词;value是数字类型,保存该单词出现的次数。 (3)遍历(1)中得到的字符串数组,对于每一个单词,考察Map的key中是否出现过该单词,如果没出现过,map中增加一个元素,key为该单词,value为1(

    通过学习学会了文本的访问,了解一点哈希表用途.经过网上查找做成了下面查询文章重复词的JAVA程序. 1 思 思路: (1)将文章(一个字符串存储)按空格进行拆分(split)后,存储到一个字符串(单词 ...

随机推荐

  1. 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

    通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...

  2. Shell替换

    如果表达式中包含特殊字符,Shell 将会进行替换.例如,在双引号中使用变量就是一种替换,转义字符也是一种替换. #!/bin/bash a= echo -e "Value of a is ...

  3. 聊聊Unity项目管理的那些事:Git-flow和Unity

    0x00 前言 目前所在的团队实行敏捷开发已经有了一段时间了.敏捷开发中重要的一个话题便是如何对项目进行恰当的版本管理.项目从最初使用svn到之后的Git One Track策略再到现在的GitFlo ...

  4. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?

    今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...

  5. android 使用Tabhost 发生could not create tab content because could not find view with id 错误

    使用Tabhost的时候经常报:could not create tab content because could not find view with id 错误. 总结一下发生错误的原因,一般的 ...

  6. 《Django By Example》第二章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:翻译完第一章后,发现翻译第二章的速 ...

  7. javascript中的操作符详解1

    好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解 ...

  8. C#多线程之线程同步篇2

    在上一篇C#多线程之线程同步篇1中,我们主要学习了执行基本的原子操作.使用Mutex构造以及SemaphoreSlim构造,在这一篇中我们主要学习如何使用AutoResetEvent构造.Manual ...

  9. [数据结构]——堆(Heap)、堆排序和TopK

    堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...

  10. 注释生成Api文档

    1.开发背景 最近一直在写dubbo接口,以前总是用word文档写接口描述然后发给别人.现在太多了,而且跟别人对接联调的人家急着用,根本没时间去写word文档.那就想想怎么用doc文档注释自动生成接口 ...