MapReduce-MulitipleOutputs实现自己定义输出到多个文件夹
输入源数据例子:
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
MapReduce-MulitipleOutputs实现自己定义输出到多个文件夹的更多相关文章
- 第3节 mapreduce高级:7、自定义outputformat实现输出到不同的文件夹下面
2.1 需求 现在有一些订单的评论数据,需求,将订单的好评与差评进行区分开来,将最终的数据分开到不同的文件夹下面去,数据内容参见资料文件夹,其中数据第九个字段表示好评,中评,差评.0:好评,1:中评, ...
- 模块化定义JS,让统一文件夹内相同的变量不冲突
两种方法: 1.(function(){……编写代码……})() //先声明一个函数,声明完后直接调用 2.!function(){……编写代码……}()
- Hadoop MultipleOutputs 结果输出到多个文件夹 出现数据不全,部分文件为空
如题:出现下图中的情况(设置reduceNum=5) 感觉很奇怪,排除了很久,终于发现是一个第二次犯的错误:丢了这句 this.mOutputs.close(); 加上这句,一切恢复正常!
- hadoop编程小技巧(7)---自己定义输出文件格式以及输出到不同文件夹
代码測试环境:Hadoop2.4 应用场景:当须要定制输出数据格式时能够採用此技巧,包含定制输出数据的展现形式.输出路径.输出文件名称称等. Hadoop内置的输出文件格式有: 1)FileOutpu ...
- MapReduce剖析笔记之八: Map输出数据的处理类MapOutputBuffer分析
在上一节我们分析了Child子进程启动,处理Map.Reduce任务的主要过程,但对于一些细节没有分析,这一节主要对MapOutputBuffer这个关键类进行分析. MapOutputBuffer顾 ...
- OutputFormat---自定义输出方式
简介 可以自定义输出的格式和文件,例如包含某字段的输出到一个指定文件,不包含某字段的输出到另一个文件. 案例 数据 www.nevesettle.com www.baidu.com www.qq.co ...
- hadoop拾遗(五)---- mapreduce 输出到多个文件 / 文件夹
今天要把HBase中的部分数据转移到HDFS上,想根据时间戳来自动输出到以时间戳来命名的每个文件夹下.虽然以前也做过相似工作,但有些细节还是忘记了,所以这次写个随笔记录一下. package com. ...
- 随着MapReduce job实现去加重,多种输出文件夹
总结以往的工作中遇到的一个问题. 背景: 操作和维护与scribe从apacheserver一再被推到日志记录,所以在这里ETL处理正在进行的重.有根据业务的输出类型是用于多文件夹一个需求.方便挂分区 ...
- hadoop1.2.1 MultipleOutputs将结果输出到多个文件或文件夹
hadoop1.2.1 MultipleOutputs将结果输出到多个文件或文件夹 博客分类:http://tydldd.iteye.com/blog/2053867 hadoop hadoop1 ...
随机推荐
- httpd2.4出现AH00025: configuration error
log文件 安装的是包含ssl的版本,需要加载 LoadModule authz_core_module modules/mod_authz_core.so
- [CF396E]On Iteration of One Well-Known Function
题意:给定$n=\prod\limits_{i=1}^mp_i^{a_i}$,求$\varphi\left(\cdots\varphi\left(n\right)\cdots\right)$(有$k$ ...
- [ZOJ3316]Game
题意:有一个棋盘,棋盘上有一些棋子,两个人轮流拿棋,第一个人可以随意拿,以后每一个人拿走的棋子与上一个人拿走的棋子的曼哈顿距离不得超过$L$,无法拿棋的人输,问后手能否胜利 把棋子看做点,如果两个棋子 ...
- Java高级架构师(一)第26节:测试并调整登录的业务功能
主Index的处理Java: package com.sishuok.architecture1; import org.springframework.beans.factory.annotatio ...
- 基于java过滤器实现的ajax跨域解决方案
http://software.dzhuvinov.com/cors-filter-configuration.html
- 搭建vue全家桶
1.直接利用vue-cli脚手架快速搭建 (1)全局安装vue-cli npm install -g vue-cli (2)创建项目 vue init webpack-simple my-projec ...
- 建立DB-LINK和建立视图
在系统数据通信间经常会有数据库的数据直接引用,使用视图VIEW的方式实现.视图调用通常会有两种情况,一种是同一数据库的视图,一种是跨数据库的视图. 在同一数据库地址不同用户下,不过不同的用户视图调用需 ...
- delphi 接口Interface
学习 delphi 接口 一切都是纸老虎!!! 第四章 接口 前不久,有位搞软件的朋友给我出了个谜语.谜面是“相亲”,让我猜一软件术语.我大约想了一分钟,猜 出谜底是“面向对象”.我 ...
- javascript专业八级测试答案整理
前几天社区的群里森破发了一个这样的链接: http://ourjs.com/detail/52fb82e13bd19c4814000001 做了一遍后突然对人生感到了迷茫,本着不能只有我一个人伤心的原 ...
- 构建高性能web站点-1
以下为阅读<构建高性能web站点>郭欣 著 这本书的适合读者: 1.编写web程序.关心站点性能,并且希望自己做的更加出色的开发人员 2.关心性能和可用性的web架构师 3.希望构建高性能 ...