输入源数据例子:

Source1-0001
Source2-0002
Source1-0003
Source2-0004
Source1-0005
Source2-0006
Source3-0007
Source3-0008

描写叙述:

  • Source1开头的数据属于集合A。
  • Source2开头的数据属于集合B;
  • Source3开头的数据即属于集合A,也属于集合B。

输出要求:

  • 完整保留集合A数据(包括Source1、Source3开头数据)
  • 完整保留集合B数据(包括Source2、Source3开头数据)

程序实现:

import java.io.IOException;
import java.util.List;
import java.util.Map; import org.apache.hadoop.conf.Configuration;
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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.mahout.common.AbstractJob; import com.yhd.common.util.HadoopUtil; /**
* AbstractJob 是mahout的Job模板,能够不使用该模板,
* 实则的核心部分在于MultipleOutputs部分
*
* @author ouyangyewei
*
*/
public class TestMultipleOutputsJob extends AbstractJob {
@Override
public int run(String[] args) throws Exception {
addInputOption();
addOutputOption(); Map<String, List<String>> parseArgs = parseArguments(args);
if(parseArgs==null){
return -1;
} HadoopUtil.delete(getConf(), getOutputPath()); Configuration conf = new Configuration();
conf.setInt("mapred.reduce.tasks", 4);
conf.set("mapred.job.queue.name", "pms");
conf.set("mapred.child.java.opts", "-Xmx3072m");
conf.set("mapreduce.reduce.shuffle.memory.limit.percent", "0.05"); Job job = new Job(new Configuration(conf));
job.setJobName("TestMultipleOutputsJob");
job.setJarByClass(TestMultipleOutputsJob.class);
job.setMapperClass(MultipleMapper.class);
job.setNumReduceTasks(0);
FileInputFormat.setInputPaths(job, this.getInputPath());
FileOutputFormat.setOutputPath(job, this.getOutputPath()); /** 输出文件格式将为:Source1-m-**** */
MultipleOutputs.addNamedOutput(job, "Source1", TextOutputFormat.class, Text.class, Text.class);
/** 输出文件格式将为:Source2-m-**** */
MultipleOutputs.addNamedOutput(job, "Source2", TextOutputFormat.class, Text.class, Text.class); boolean suceeded = job.waitForCompletion(true);
if(!suceeded) {
return -1;
}
return 0;
} /**
*
* @author ouyangyewei
*
*/
public static class MultipleMapper extends Mapper<LongWritable, Text, Text, Text> {
private MultipleOutputs<Text, Text> mos = null; @Override
protected void setup(Context context
) throws IOException, InterruptedException {
mos = new MultipleOutputs<Text, Text>(context);
} public void map(LongWritable key, Text value, Context context
) throws IOException, InterruptedException {
String line = value.toString();
String[] tokenizer = line.split("-"); if (tokenizer[0].equals("Source1")) {
/** 集合A的数据 */
mos.write("Source1", new Text(tokenizer[0]), tokenizer[1]);
} else if (tokenizer[0].equals("Source2")) {
/** 集合B的数据 */
mos.write("Source2", new Text(tokenizer[0]), tokenizer[1]);
} /** 集合A交集合B的数据 */
if (tokenizer[0].equals("Source3")) {
mos.write("Source1", new Text(tokenizer[0]), tokenizer[1]);
mos.write("Source2", new Text(tokenizer[0]), tokenizer[1]);
}
} protected void cleanup(Context context
) throws IOException, InterruptedException {
mos.close();
}
} /**
* @param args
*/
public static void main(String[] args) {
System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
System.setProperty("javax.xml.parsers.SAXParserFactory",
"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); TestMultipleOutputsJob instance = new TestMultipleOutputsJob();
try {
instance.run(args);
} catch (Exception e) {
e.printStackTrace();
}
}
}

使用hadoop jar命令调度执行jar包代码:

hadoop jar bigdata-datamining-1.0-user-trace-jar-with-dependencies.jar com.yhd.datamining.data.usertrack.offline.job.mapred.TestMultipleOutputsJob \
--input /user/pms/workspace/ouyangyewei/testMultipleOutputs \
--output /user/pms/workspace/ouyangyewei/testMultipleOutputs/output

程序执行以后,输出的结果:

[pms@yhd-jqhadoop39 /home/pms/workspace/ouyangyewei]
$hadoop fs -ls /user/pms/workspace/ouyangyewei/testMultipleOutputs/output
Found 4 items
-rw-r--r-- 3 pms pms 65 2014-12-16 09:18 /user/pms/workspace/ouyangyewei/testMultipleOutputs/output/Source1-m-00000
-rw-r--r-- 3 pms pms 65 2014-12-16 09:18 /user/pms/workspace/ouyangyewei/testMultipleOutputs/output/Source2-m-00000
-rw-r--r-- 3 pms pms 0 2014-12-16 09:18 /user/pms/workspace/ouyangyewei/testMultipleOutputs/output/_SUCCESS
-rw-r--r-- 3 pms pms 0 2014-12-16 09:18 /user/pms/workspace/ouyangyewei/testMultipleOutputs/output/part-m-00000 [pms@yhd-jqhadoop39 /home/pms/workspace/ouyangyewei]
$hadoop fs -cat /user/pms/workspace/ouyangyewei/testMultipleOutputs/output/Source1-m-00000
Source1 0001
Source1 0003
Source1 0005
Source3 0007
Source3 0008 [pms@yhd-jqhadoop39 /home/pms/workspace/ouyangyewei]
$hadoop fs -cat /user/pms/workspace/ouyangyewei/testMultipleOutputs/output/Source2-m-00000
Source2 0002
Source2 0004
Source2 0006
Source3 0007
Source3 0008

补充于2014-12-18:

这样的方式的缺陷是会产生非常多类似Source1或Source2开头的子文件,一种非常好的方式就是指定baseOutputPath,将Source1开头的文件放在同一个文件夹中管理

对上述代码进行改写实现文件夹管理:

public void map(LongWritable key, Text value, Context context
) throws IOException, InterruptedException {
String line = value.toString();
String[] tokenizer = line.split("-"); if (tokenizer[0].equals("Source1")) {
/** 集合A的数据 */
mos.write("Source1",
new Text(tokenizer[0]),
tokenizer[1],
"Source1/part");
} else if (tokenizer[0].equals("Source2")) {
/** 集合B的数据 */
mos.write("Source2",
new Text(tokenizer[0]),
tokenizer[1],
"Source2/part");
} /** 集合A交集合B的数据 */
if (tokenizer[0].equals("Source3")) {
mos.write("Source1",
new Text(tokenizer[0]),
tokenizer[1],
"Source1/part"); mos.write("Source2",
new Text(tokenizer[0]),
tokenizer[1],
"Source2/part");
}
}

程序执行以后,输出的结果:

$hadoop fs -ls /user/pms/workspace/ouyangyewei/testUsertrack/job1Output
Found 4 items
-rw-r--r-- 3 pms pms 0 2014-12-18 14:11 /user/pms/workspace/ouyangyewei/testUsertrack/job1Output/_SUCCESS
-rw-r--r-- 3 pms pms 0 2014-12-18 14:11 /user/pms/workspace/ouyangyewei/testUsertrack/job1Output/part-r-00000
drwxr-xr-x - pms pms 0 2014-12-18 14:11 /user/pms/workspace/ouyangyewei/testUsertrack/job1Output/Source1
drwxr-xr-x - pms pms 0 2014-12-18 14:11 /user/pms/workspace/ouyangyewei/testUsertrack/job1Output/Source2 [pms@yhd-jqhadoop39 /home/pms/workspace/ouyangyewei/testUsertrack]
$hadoop fs -ls /user/pms/workspace/ouyangyewei/testUsertrack/job1Output/Source1
Found 1 items
-rw-r--r-- 3 pms pms 65 2014-12-18 14:11 /user/pms/workspace/ouyangyewei/testUsertrack/job1Output/Source1/part-r-00000 [pms@yhd-jqhadoop39 /home/pms/workspace/ouyangyewei/testUsertrack]
$hadoop fs -ls /user/pms/workspace/ouyangyewei/testUsertrack/job1Output/Source2
Found 1 items
-rw-r--r-- 3 pms pms 65 2014-12-18 14:11 /user/pms/workspace/ouyangyewei/testUsertrack/job1Output/Source2/part-r-00000

能够參考下:http://dirlt.com/mapred.html

MapReduce-MulitipleOutputs实现自己定义输出到多个文件夹的更多相关文章

  1. 第3节 mapreduce高级:7、自定义outputformat实现输出到不同的文件夹下面

    2.1 需求 现在有一些订单的评论数据,需求,将订单的好评与差评进行区分开来,将最终的数据分开到不同的文件夹下面去,数据内容参见资料文件夹,其中数据第九个字段表示好评,中评,差评.0:好评,1:中评, ...

  2. 模块化定义JS,让统一文件夹内相同的变量不冲突

    两种方法: 1.(function(){……编写代码……})()   //先声明一个函数,声明完后直接调用 2.!function(){……编写代码……}()

  3. Hadoop MultipleOutputs 结果输出到多个文件夹 出现数据不全,部分文件为空

    如题:出现下图中的情况(设置reduceNum=5) 感觉很奇怪,排除了很久,终于发现是一个第二次犯的错误:丢了这句 this.mOutputs.close(); 加上这句,一切恢复正常!

  4. hadoop编程小技巧(7)---自己定义输出文件格式以及输出到不同文件夹

    代码測试环境:Hadoop2.4 应用场景:当须要定制输出数据格式时能够採用此技巧,包含定制输出数据的展现形式.输出路径.输出文件名称称等. Hadoop内置的输出文件格式有: 1)FileOutpu ...

  5. MapReduce剖析笔记之八: Map输出数据的处理类MapOutputBuffer分析

    在上一节我们分析了Child子进程启动,处理Map.Reduce任务的主要过程,但对于一些细节没有分析,这一节主要对MapOutputBuffer这个关键类进行分析. MapOutputBuffer顾 ...

  6. OutputFormat---自定义输出方式

    简介 可以自定义输出的格式和文件,例如包含某字段的输出到一个指定文件,不包含某字段的输出到另一个文件. 案例 数据 www.nevesettle.com www.baidu.com www.qq.co ...

  7. hadoop拾遗(五)---- mapreduce 输出到多个文件 / 文件夹

    今天要把HBase中的部分数据转移到HDFS上,想根据时间戳来自动输出到以时间戳来命名的每个文件夹下.虽然以前也做过相似工作,但有些细节还是忘记了,所以这次写个随笔记录一下. package com. ...

  8. 随着MapReduce job实现去加重,多种输出文件夹

    总结以往的工作中遇到的一个问题. 背景: 操作和维护与scribe从apacheserver一再被推到日志记录,所以在这里ETL处理正在进行的重.有根据业务的输出类型是用于多文件夹一个需求.方便挂分区 ...

  9. hadoop1.2.1 MultipleOutputs将结果输出到多个文件或文件夹

    hadoop1.2.1 MultipleOutputs将结果输出到多个文件或文件夹 博客分类:http://tydldd.iteye.com/blog/2053867 hadoop   hadoop1 ...

随机推荐

  1. Codechef REBXOR

    Read problems statements in Mandarin and Russian. Translations in Vietnamese to be uploaded soon. Ni ...

  2. 【点分治】hdu5016 Mart Master II

    点分治好题. ①手动开栈. ②dp预处理每个点被哪个市场控制,及其距离是多少,记作pair<int,int>数组p. ③设dis[u].first为u到重心s的距离,dis[u].seco ...

  3. 十. 图形界面(GUI)设计5.布局设计

    在界面设计中,一个容器要放置许多组件,为了美观,为组件安排在容器中的位置,这就是布局设计.java.awt中定义了多种布局类,每种布局类对应一种布局的策略.常用的有以下布局类: FlowLayout, ...

  4. Java高级架构师(一)第28节:Index、商品详细页和购物车

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...

  5. How to enable Hibernate option in windows 2008 R2 server?

    http://velshare.blogspot.com/2013/02/how-to-enable-hibernate-option-in.html 1) To enable the Hiberna ...

  6. HTTPS.SYS怎样使用HTTPS

    HTTPS.SYS怎样使用HTTPS 参考了MORMOT的官方文档:http://blog.synopse.info/post/2013/09/04/HTTPS-communication-in-mO ...

  7. 【java】JDK安装后,没有配置环境变量,也可以java -version查看到版本信息

    JDK安装后,没有配置环境变量,也可以java -version查看到版本信息 原因是:jdk安装过程,java.javaw.javaws三个命令被复制到C:\windows\system32目录下 ...

  8. 第三天 ThinkPHP手把手高速拼接站点(三)

    6月1日,小雨." 梅子金黄杏子肥,麦花雪白菜花稀. 日长篱落无人过,唯有蜻蜓蛱蝶飞." 七.MVC模式 ThinkPHP的MVC开发机制例如以下: M  Model层    模型 ...

  9. LNMP第二部分nginx、php配置

    内容概要:一. nginx.confvim /usr/local/nginx/conf/nginx.conf //清空原来的配置,加入如下内容:user nobody nobody;worker_pr ...

  10. websocket 和 socket.io 之间的区别

    socket.io封装了websocket,同时包含了其它的连接方式,比如Ajax.原因在于不是所有的浏览器都支持websocket,通过socket.io的封装,你不用关心里面用了什么连接方式.你在 ...