Hadoop MultiOutputs 实现
来源:互联网 发布:魅蓝note5网络设置 编辑:程序博客网 时间:2024/06/07 06:48
工作中有人问 MultiOutputs 实现为啥在指定reduce数为1时 结果文件数依然是 好多个?这其实由其实现逻辑决定的。
在MR中 一般job都可以通过map reduce 默认的OutputCollector 实现 写入作业初始化时指定格式的输出中,只能一个文件格式。当需要将结果分门别类区分或者使用不同格式存储在多个文件结果中时 就需要 MultiOutputs了。
MultiOutputs 添加输出得api
/** * Adds a named output for the job. * <p/> * * @param conf job conf to add the named output * @param namedOutput named output name, it has to be a word, letters * and numbers only, cannot be the word 'part' as * that is reserved for the * default output. * @param outputFormatClass OutputFormat class. * @param keyClass key class * @param valueClass value class */ public static void addNamedOutput(JobConf conf, String namedOutput, Class<? extends OutputFormat> outputFormatClass, Class<?> keyClass, Class<?> valueClass) { addNamedOutput(conf, namedOutput, false, outputFormatClass, keyClass, valueClass); } /** * Adds a multi named output for the job. * <p/> * * @param conf job conf to add the named output * @param namedOutput named output name, it has to be a word, letters * and numbers only, cannot be the word 'part' as * that is reserved for the * default output. * @param outputFormatClass OutputFormat class. * @param keyClass key class * @param valueClass value class */ public static void addMultiNamedOutput(JobConf conf, String namedOutput, Class<? extends OutputFormat> outputFormatClass, Class<?> keyClass, Class<?> valueClass) { addNamedOutput(conf, namedOutput, true, outputFormatClass, keyClass, valueClass); }
通过以上2个api可以设定 文件命名前缀 文件输出格式 等,每种结果格式可以不一样。
在MultiOutputs 实现中 通过getCollector方法实例化一个OutputCollector,实现输出
public OutputCollector getCollector(String namedOutput, String multiName, Reporter reporter) throws IOException { checkNamedOutputName(namedOutput); if (!namedOutputs.contains(namedOutput)) { throw new IllegalArgumentException("Undefined named output '" + namedOutput + "'"); } boolean multi = isMultiNamedOutput(conf, namedOutput); if (!multi && multiName != null) { throw new IllegalArgumentException("Name output '" + namedOutput + "' has not been defined as multi"); } if (multi) { checkTokenName(multiName); } String baseFileName = (multi) ? namedOutput + "_" + multiName : namedOutput; final RecordWriter writer = getRecordWriter(namedOutput, baseFileName, reporter); return new OutputCollector() { @SuppressWarnings({"unchecked"}) public void collect(Object key, Object value) throws IOException { writer.write(key, value); } }; }
上面中 RecordWriter 是 MultiOutputs 中的内部类 InternalFileOutputFormat 实现,
baseFileName是文件名前缀,后面用于 初始化文件名,如果是multi的话 文件名前缀由
namedOutput + "_" + multiName组成,否则是
namedOutput,看下该类里getRecordWriter()实现中 关键出 得到文件名是如何实现的?
String nameOutput = job.get(CONFIG_NAMED_OUTPUT, null);
String fileName = getUniqueName(job, baseFileName);
其中getUniqueName 方法 沿用的FileOutputFormat 的实现。
public static String getUniqueName(JobConf conf, String name) { int partition = conf.getInt("mapred.task.partition", -1); if (partition == -1) { throw new IllegalArgumentException( "This method can only be called from within a Job"); } String taskType = (conf.getBoolean("mapred.task.is.map", true)) ? "m" : "r"; NumberFormat numberFormat = NumberFormat.getInstance(); numberFormat.setMinimumIntegerDigits(5); numberFormat.setGroupingUsed(false); return name + "-" + taskType + "-" + numberFormat.format(partition); }
无论是map 还是reduce 中实现的MultiOutputs 输出 ,均 通过 mapred.task.partition 实现文件名构造, 通过name,type(map or reduce )以及 map分区编号 表示一个文件名。
所以 使用该类时 文件数并不是由reduce个数决定,而是 name 的组成(或者说是否multi)以及 mapred.task.partition决定。
0 0
- Hadoop MultiOutputs 实现
- 【hadoop蜜汁问题解决】Multioutputs按照key输出多个文件
- 【Hadoop】hadoop中实现ListWritable
- hadoop实现原理
- 利用Cloudera实现Hadoop
- Hadoop SequenceFile FileInputFormat实现
- hadoop rackawareness实现
- Hadoop中的RPC实现
- hadoop writable的实现
- hadoop任务监控实现
- Hadoop 实现Rackawareness
- Hadoop 实现矩阵相乘
- hadoop实现kmeans二
- hadoop hbase 实现 servlet
- Hadoop 实现kmeans 算法
- 利用Cloudera实现Hadoop
- Hadoop 实现Writable接口
- Hadoop 压缩实现分析
- Maven 操作入门,来自 hang.gao 演示-慢慢研究
- 反白处理
- ActiveMQ队列特性:组合队列(Composite Destinations)
- cocos2d-x3.0 + vs2012环境配置
- OJ_1121
- Hadoop MultiOutputs 实现
- 做一个风投怎么样
- 查找最小的k个元素 C++实现
- 《JavaScript启示录》
- hypervisor
- 解决织梦 \include\userlogin.class.php on line 21 报错的方法
- cmMergePaint
- android 每次重启手机自己的程序会冒出已停止对话框
- ActiveMQ队列特性:删除不活动的队列(Delete Inactive Destinations)