map获取输入文件名称和GenericOptionsParser使用
来源:互联网 发布:星际战甲库伯数据模块 编辑:程序博客网 时间:2024/06/06 00:08
该文章中实现业务需求的方法不可取(其实可以使用hadoop提供的多输入来实现),但是该例子去能很好的展现在map函数中怎么拿到输入文件的名称:
原文地址:http://datamachine.iteye.com/blog/1963256
选择Hadoop,低成本和高扩展性是主要原因,但但它的开发效率实在无法让人满意。
以关联计算为例。
假设:HDFS上有2个文件,分别是客户信息和订单信息,customerID是它们之间的关联字段。如何进行关联计算,以便将客户名称添加到订单列表中?
一般方法是:输入2个源文件。根据文件名在Map中处理每条数据,如果是Order,则在foreign key上加标记”O”,形成combined key;如果是Customer则做标记”C”。Map之后的数据按照key分区,再按照combined key分组排序。最后在reduce中合并结果再输出。
实现代码:
public static class JMapper extends Mapper<LongWritable, Text, TextPair, Text> {
//mark every row with "O" or "C" according to file name
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String pathName = ((FileSplit) context.getInputSplit()).getPath().toString();
if (pathName.contains("order.txt")) {//identify order by file name
String values[] = value.toString().split("\t");
TextPair tp = new TextPair(new Text(values[1]), new Text("O"));//mark with "O"
context.write(tp, new Text(values[0] + "\t" + values[2]));
}
if (pathName.contains("customer.txt")) {//identify customer by file name
String values[] = value.toString().split("\t");
TextPair tp = new TextPair(new Text(values[0]), new Text("C"));//mark with "C"
context.write(tp, new Text(values[1]));
}
}
}
public static class JPartitioner extends Partitioner<TextPair, Text> {
//partition by key, i.e. customerID
@Override
public int getPartition(TextPair key, Text value, int numParititon) {
return Math.abs(key.getFirst().hashCode() * 127) % numParititon;
}
}
public static class JComparator extends WritableComparator {
//group by muti-key
public JComparator() {
super(TextPair.class, true);
}
@SuppressWarnings("unchecked")
public int compare(WritableComparable a, WritableComparable b) {
TextPair t1 = (TextPair) a;
TextPair t2 = (TextPair) b;
return t1.getFirst().compareTo(t2.getFirst());
}
}
public static class JReduce extends Reducer<TextPair, Text, Text, Text> {
//merge and output
protected void reduce(TextPair key, Iterable<Text> values, Context context) throws IOException,InterruptedException {
Text pid = key.getFirst();
String desc = values.iterator().next().toString();
while (values.iterator().hasNext()) {
context.write(pid, new Text(values.iterator().next().toString() + "\t" + desc));
}
}
}
public class TextPair implements WritableComparable<TextPair> {
//make muti-key
private Text first;
private Text second;
public TextPair() {
set(new Text(), new Text());
}
public TextPair(String first, String second) {
set(new Text(first), new Text(second));
}
public TextPair(Text first, Text second) {
set(first, second);
}
public void set(Text first, Text second) {
this.first = first;
this.second = second;
}
public Text getFirst() {
return first;
}
public Text getSecond() {
return second;
}
public void write(DataOutput out) throws IOException {
first.write(out);
second.write(out);
}
public void readFields(DataInput in) throws IOException {
first.readFields(in);
second.readFields(in);
}
public int compareTo(TextPair tp) {
int cmp = first.compareTo(tp.first);
if (cmp != 0) {
return cmp;
}
return second.compareTo(tp.second);
}
}
public static void main(String agrs[]) throws IOException, InterruptedException, ClassNotFoundException {
//job entrance
Configuration conf = new Configuration();
GenericOptionsParser parser = new GenericOptionsParser(conf, agrs);
String[] otherArgs = parser.getRemainingArgs();
if (agrs.length < 3) {
System.err.println("Usage: J <in_path_one> <in_path_two> <output>");
System.exit(2);
}
Job job = new Job(conf, "J");
job.setJarByClass(J.class);//Join class
job.setMapperClass(JMapper.class);//Map class
job.setMapOutputKeyClass(TextPair.class);//Map output key class
job.setMapOutputValueClass(Text.class);//Map output value class
job.setPartitionerClass(JPartitioner.class);//partition class
job.setGroupingComparatorClass(JComparator.class);//condition group class after partition
job.setReducerClass(Example_Join_01_Reduce.class);//reduce class
job.setOutputKeyClass(Text.class);//reduce output key class
job.setOutputValueClass(Text.class);//reduce ouput value class
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));//one of source files
FileInputFormat.addInputPath(job, new Path(otherArgs[1]));//another file
FileOutputFormat.setOutputPath(job, new Path(otherArgs[2]));//output path
System.exit(job.waitForCompletion(true) ? 0 : 1);//run untill job ends
}
不能直接使用原始数据,而是要搞一堆代码处理标记,并绕过MapReduce原本的架构,最后从底层设计并计算数据之间的关联关系。这还是最简单的关联计算,如果用MapReduce进行多表关联或逻辑更复杂的关联计算,复杂度会呈几何级数递增。
- map获取输入文件名称和GenericOptionsParser使用
- php获取文件名称和扩展名
- php获取文件名称和扩展名
- php获取文件名称和扩展名
- 在map函数中获取当前记录来自的文件名称
- 辅助类GenericOptionsParser,Tool和ToolRunner
- mapreduce 辅助类GenericOptionsParser,Tool和ToolRunner
- 使用vb.net 获取文件夹下选中文件的文件名称
- 文件对话框获取文件的路径和文件名称
- 关于Struts2 上传文件获取文件名称和类型(标准做法)
- java文件上传和下载 如何获取文件名称
- python 获取文件名称和读取写入文件小结
- 获取时间用于文件名称
- c# 获取文件名称
- 获取路径文件名称
- 获取文件夹内文件名称
- 采用对话框获取文件名称
- VTK中经常使用的头文件和LIB文件名称
- nginx 全局变量
- AJAX实现随笔提示功能
- 张孝祥整理的JAVA面试题目(八)(每天一更)
- CentOS──xxx is not in the sudoers file解决方法
- Basic Level 1012. 数字分类 (20)
- map获取输入文件名称和GenericOptionsParser使用
- 如何在代码中设置imageview的大小
- MyBatis 分页代码实现
- 子数组合并算法之向右循环
- 基本配置及安全级别security-level
- vs2010编译boost c++库 && blitz++
- Memcached源码分析之网络连接建立
- LInux 描述符GDT, IDT & LDT结构定义
- 《C++ Primer第五版》读书笔记--插播--宏相对于inline的优势