1、默认情况下生成的文件名是part-r-00000格式,想要自定义生成输出文件名可以使用org.apache.hadoop.mapreduce.lib.output.MultipleOutputs类用来写出

2、MultipleOutputs类需要在Reduce的setup()方法初始化,最好在cleanup()中关闭

3、这个时候还会生产成part-r-000000这种文件,发现是里面是空的,需要 LazyOutputFormat.setOutputFormatClass(job, TextOutputFormat.class);

4、MultipleOutputs类的write()方法有几个重载的函数

write(KEYOUT key, VALUEOUT value, String baseOutputPath)
如果baseOutputPath带/,那么输出路径就是baseOutputPath + -r-00000,比如baseOutpuPath="/PUFA/" + key.toString(),输出文件路径就是/PUFA/0000000001-r-000000
不带/,输出路径就是FileOutputFormat.setOutputPath(job, outPutPath)下面,比如baseOutputPath=key.toString(),ouputPath=/trx,输出文件的路径就是/trx/0000000001-r-000000

write方法如果是带namedOutput参数的,需要在运行主类上面指定namedOutput,
MultipleOutputs.addNamedOutput(job, "PFBANK", TextOutputFormat.class, JournalTrxDataSet.class, NullWritable.class);
MultipleOutputs.addNamedOutput(job, "ZSBANK", TextOutputFormat.class, JournalTrxDataSet.class, NullWritable.class);
write(String namedOutput, K key, V value, String baseOutputPath) 
write(String namedOutput, K key, V value) 
这两种况和上面方法差不多,就是通过namedOutput对一组reduce处理的结果输出到不同的文件夹中,如果没有baseOutputPath,会输出到FileOutputFormat.setOutputPath()目录
  if (Integer.parseInt(key.toString()) >= 500000){
mos.write("PFBANK", journalTrxDataSet, NullWritable.get(), "/PUFA/" + key.toString());
}else if(Integer.parseInt(key.toString()) < 500000){
mos.write("ZSBANK", journalTrxDataSet, NullWritable.get(), "/ZHAOSHANG/" + key.toString());
}

注意:有的时候会出现_SUCCESS文件和reduce输出的文件不在同一个目录,这是因为FileOutputFormat.setOutputPaht()和MultipleOutputs类的write()方法设置的baseOutputPath不一样所致,_SUCCESS文件始终在FileOutputFormat.setOutputPaht()设定的路径上

有的时候会报一些莫名其妙的错的话,可能是LazyOutputFormat.setOutputFormatClass()和MultipleOutputs.addNamedOutput()的formatclass参数有关

最后附上完整代码

当时我们的需求是,需要分析统计银行各个终端的交易情况,当时我们数据量也不太多,领导说尽可能简单点做,当时统计纬度有两种,一种是按照机器,一种是按照分行,所以直接使用了同一个mapreduce来完成,当然,下面代码只是统计机器的,分行的维度还没写上。当时mr程序是独立的一个模块,在数据采集完成后,会直接使用sh或cmd命令调用这个jar包,文件名当成启动参数传递过来。文件需要自定义

package com.xhy.xgg.mapreduce;

import com.xhy.xgg.common.HDFSCommand;
import com.xhy.xgg.common.enums.StatisticDemensionEnums;
import com.xhy.xgg.entity.JournalTrxDataSet;
import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Partitioner;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.LazyOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.stereotype.Service; import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date; @Slf4j
@Service
public class MapReduceTest { @Value("${data-set.output-path}")
private String dataCollectionOutputPath;
@Value("${data-collection.output-path}")
private String dataCollectionIutputPath; @Value("${data-collection.hdfsURI}")
private String hdfsURI; @Value("${mr-run-mode.value}")
private String mrRunMode; @PostConstruct
public void executeMRJob(StatisticDemensionEnums statisticDemensionEnums)
throws IOException, ClassNotFoundException, InterruptedException { log.info(">> executeMRJob start execute");
Configuration conf = new Configuration();
conf.set("dfs.blocksize", "67108864");
conf.set("dfs.replication", "1");
conf.set("mapreduce.framework.name", mrRunMode);
conf.set("fs.defaultFS", hdfsURI);
Job job;
job = Job.getInstance(conf, "JournalDataProcessService");
job.setJarByClass(com.xhy.xgg.mapreduce.TerminalJournalDataService.class);
job.getConfiguration().set("statisticDemensionEnums", String.valueOf(statisticDemensionEnums.getIndex()));
job.setMapperClass(com.xhy.xgg.mapreduce.MapReduceTest.JournalDataMapper.class);
job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(JournalTrxDataSet.class);
job.setReducerClass(com.xhy.xgg.mapreduce.MapReduceTest.JournalDataReducer.class);
job.setOutputKeyClass(JournalTrxDataSet.class);
job.setOutputValueClass(NullWritable.class);
job.setPartitionerClass(com.xhy.xgg.mapreduce.MapReduceTest.JournalDataPartitioner.class);
// job.setSortComparatorClass(JournalTrxDataComparator.class);
job.setNumReduceTasks(3);
Path inputPath = new Path(dataCollectionIutputPath + File.separator + "esbTrx" + File.separator
+ hdfsFileName); log.info("-- executeMRJob inputPath = {}", inputPath.toString()); FileInputFormat.addInputPath(job, inputPath); String outPutPathData = ""; outPutPathData = dataCollectionOutputPath + "_" + new SimpleDateFormat("yyyyMMdd").format(new Date());
try {
if (HDFSCommand.exists(conf, hdfsURI, outPutPathData)) {
HDFSCommand.delete(conf, hdfsURI, outPutPathData);
}
} catch (Exception e) {
// TODO Auto-generated catch block
log.error("<< executeMRJob exception, message {}", e.getMessage());
}
Path outPutPath = new Path(outPutPathData);
FileOutputFormat.setOutputPath(job, outPutPath);
MultipleOutputs.addNamedOutput(job, "PFBANK", TextOutputFormat.class, JournalTrxDataSet.class, NullWritable.class);
MultipleOutputs.addNamedOutput(job, "ZSBANK", TextOutputFormat.class, JournalTrxDataSet.class, NullWritable.class); LazyOutputFormat.setOutputFormatClass(job, TextOutputFormat.class); System.exit(job.waitForCompletion(true) ? 0 : 1);
} public void start() throws Exception {
executeMRJob(StatisticDemensionEnums.TERMINAL);
} private String hdfsFileName = "journal_test.txt"; private static class JournalDataReducer extends Reducer<Text, JournalTrxDataSet, JournalTrxDataSet, NullWritable> { private String statisticDemensionEnums = null;
JournalTrxDataSet journalTrxDataSet = new JournalTrxDataSet(); private MultipleOutputs mos; @Override
protected void setup(Context context) throws IOException, InterruptedException {
super.setup(context);
mos = new MultipleOutputs<>(context);
statisticDemensionEnums = context.getConfiguration().get("statisticDemensionEnums"); } @Override
protected void reduce(Text key, Iterable<JournalTrxDataSet> values,
Reducer<Text, JournalTrxDataSet, JournalTrxDataSet, NullWritable>.Context context)
throws IOException, InterruptedException { String branchId = "";
String branchName = "";
String trxType = "";
double trxAmt = 0.0;
int trxCount = 0; for (JournalTrxDataSet rw : values) {
branchId = rw.getBranchId();
branchName = rw.getBranchName();
trxType = rw.getTrxType();
trxAmt += rw.getAmount();
trxCount += rw.getCount(); }
journalTrxDataSet.Set(key.toString(), branchId, branchName, trxType, trxAmt, trxCount);
if (Integer.parseInt(key.toString()) >= 500000) {
mos.write("PFBANK", journalTrxDataSet, NullWritable.get(), "/PUFA/" + key.toString());
} else if (Integer.parseInt(key.toString()) < 500000) {
mos.write("ZSBANK", journalTrxDataSet, NullWritable.get(), "/ZHAOSHANG/" + key.toString());
}
//mos.write(journalTrxDataSet, NullWritable.get(), "/PUFA/"+ key.toString());
//mos.write(journalTrxDataSet, NullWritable.get(), key.toString());
} @Override
protected void cleanup(Context context) throws IOException, InterruptedException {
super.cleanup(context);
mos.close();
} } private static class JournalDataPartitioner extends Partitioner<Text, JournalTrxDataSet> {
@Override
public int getPartition(Text key, JournalTrxDataSet value, int arg2) { if ("706010101".equals(value.getBranchId())) {
return 0;
} else if ("706010106".equals(value.getBranchId())) {
return 1;
}
return 2;
} } private static class JournalDataMapper extends Mapper<Object, Text, Text, JournalTrxDataSet> { private String statisticDemensionEnums = null; JournalTrxDataSet journalTrxDataSet = new JournalTrxDataSet(); @Override
protected void setup(Context context) throws IOException, InterruptedException {
super.setup(context);
// 上面传递过来需要map reduce的纬度,一个按照终端来统计,一个按照分行来统计
statisticDemensionEnums = context.getConfiguration().get("statisticDemensionEnums"); } @Override
protected void map(Object key, Text value, Mapper<Object, Text, Text, JournalTrxDataSet>.Context context)
throws IOException, InterruptedException { String strContent = value.toString();
String result[] = strContent.split("\\|");
String terminalId = result[0]; // terminal id
String branchId = result[1]; // branch id
String branchName = result[2]; // branch id
double amount = Double.parseDouble(result[4]); // transaction amount
String trxType = result[5];
journalTrxDataSet.Set(terminalId, branchId, branchName, trxType, amount, 1);
context.write(new Text(terminalId), journalTrxDataSet);
} } private static class JournalTrxDataComparator extends WritableComparator { protected JournalTrxDataComparator() {
super(JournalTrxDataSet.class, true);
} @Override
public int compare(WritableComparable w1, WritableComparable w2) { JournalTrxDataSet j1 = (JournalTrxDataSet) w1;
JournalTrxDataSet j2 = (JournalTrxDataSet) w2;
int resultCompare = 0;
/*
* if (j1.getAmount() == j2.getAmount()) { resultCompare = 0; } else if
* (j1.getAmount() < j2.getAmount()) { resultCompare = -1; } else {
* resultCompare = 1; }
*/
return resultCompare;// return -1,0,1
} public static void main(String[] args) { SpringApplication.run(com.xhy.xgg.mapreduce.TerminalJournalDataService.class, args);
} }
}

MapReduce输出文件名更改的更多相关文章

  1. NSLog 输出文件名、方法名、行号

    项目中经常会需要根据日志输出来寻找源代码,通过以下方法可以让它自动输出文件名.方法.行号,非常方便. 找到项目的pch文件,添加以下内容即可: ...为三个英文句号(复制粘贴后可能会变化). /** ...

  2. 关于wxFileSystemWatcher输出文件名的解决方法

    本文针对的wxWidgets版本: 2.9.4, 2.9.5,其他版本未作测试. 如果要使用 wxFileSystemWatcher 并且让其产生的wxFileSystemWatcherEvent 事 ...

  3. log4cxx用环境变量设置输出文件名

    log4cxx用环境变量设置输出文件名(金庆的专栏 2016.12)利用环境变量,可以用同一个log4j.xml来配置多个相似进程,输出日志到不同文件.例如多个BaseApp进程使用同一个BaseAp ...

  4. 统计 MapReduce 输出路径修改。

    先在上一篇MR 的104 行加入代码.jobConf.setOutputFormat(MyMultipleFilesTextOutputFormat.class); 用意是自定义 job 的输出格式: ...

  5. 如何去掉MapReduce输出的默认分隔符

    我们在用MapReduce做数据处理的时候,经常会遇到将只需要输出键或者值的情况,如context.write(new Text(record), new Text("")),这样 ...

  6. java文件名更改一直是false,看看是否是文件打开没有关

    // 更改文件名称 public static void chenckFileName(String oldFile, String newFileName) { File file = new Fi ...

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

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

  8. hadoop MapReduce —— 输出每个单词所对应的文件

    下面是四个文件及其内容. 代码实现: Mapper: package cn.tedu.invert; import java.io.IOException; import org.apache.had ...

  9. MapReduce:输出是一个文本文件,每一行第一个数字式行标,第二个数字是输入文件中每一行除行标外数字的平均值,且整数不保留小数,小数保留两位小数点

    有时候你会遇到这样的问题:你有一个表格,给出了每个人在十二月,一月和二月的收入. 表格如下: 姓名 一月 二月 三月 楚乔     200   314   3500 宇文玥     2000  332 ...

随机推荐

  1. [SCOI2016]萌萌哒

    Luogu P3295 mrclr两周前做的题让蒟蒻的我现在做? 第一眼组合计数,如果把数字相同的数位看作一个整体,除了第一位不能为零,剩下的每一位都有$0$~$9$十种. 设不同的位数为$x$,那么 ...

  2. 【接口时序】6、IIC总线的原理与Verilog实现

    一. 软件平台与硬件平台 软件平台: 1.操作系统:Windows-8.1 2.开发套件:ISE14.7 3.仿真工具:ModelSim-10.4-SE .ChipScope 硬件平台: 1. FPG ...

  3. 爬虫基础(三)-----selenium模块应用程序

    摆脱穷人思维 <三> :  培养"目标导向"的思维:  好项目永远比钱少,只要目标正确,钱总有办法解决. 一 selenium模块 什么是selenium?seleni ...

  4. (haut oj 1261 ) 地狱飞龙 利用不定积分求值

    题目链接:http://218.28.220.249:50015/JudgeOnline/problem.php?id=1261 题目描述 最近clover迷上了皇室战争,他抽到了一种地狱飞龙,很开心 ...

  5. 【问题解决方案】ImportError: No module named 'openpyxl'/‘xlrd’

    背景: 在jupyter notebook to_excle: 运行将dataframe保存为excel文件 df.to_excel('dataframe.xlsx') 时报错openpyxl rea ...

  6. 记一次innobackupex备份恢复数据库过程

    简介:以前备份都是通过mysqldump备份数据库的,由于是逻辑备份,所以采用这种备份方式数据是很安全的,跨平台.版本都很容易.凡事有利必有弊,逻辑备份在你数据库比较大时,备份.恢复数据所耗费的时间也 ...

  7. 关于CentOS7.2 控制面板不显示输入法,或者无法调出输入的问题。(已解决)

    问题描述: CentOS7.2 桌面系统控制面板突然就不显示输入法的图标,快捷键也调不出输入法. 解决方法: test@base0200: ~ $ ibus-setup 调出ibus首选项--> ...

  8. monkey日志管理

    日志管理作用 Monkey日志管理是Monkey测试中非常重要的一个环节,通过日志管理分析,可以获取当前测试对象在测试过程中是否会发生异常,以及发生的概率,同时还可以获取对应的错误信息,帮助开发定位和 ...

  9. 有关swiper动态改变数据遇到的坑(不能自动滚动,自动跟新数据,切换不正常)

    以前都觉得swiper的使用很简单,那是因为使用swiper时都是写的数据,按照官网上介绍直接初始化swiper,随便丢一个地方初始化就ok了,但是在很多需求中,我们都需要动态的改变数据,这样可能就会 ...

  10. mpvue——componets中引入vant-weapp组件

    前言 这个问题很奇葩,网上也有很多人,给了很多方法,但是我想说的是,那些方法我用了都没效果,我试了一些都没效果,因为我当时引入时报错说没有export default出来,但是一旦暴露出来就又出其他问 ...