在本示例中,我们实现了一个继承自Configured基类,并且实现了Tool接口的ReadMapfile类。这样ReadMapfile类就成为可以在Hadoop运行环境中执行的应用类。
一)准备阶段
Configured基类
Configured基类实现了Configurable接口。Configurable接口的实现使该类具有在Hadoop环境下执行时,设置/获取Hadoop各种运行上下文参数的功能。在Hadoop运行时,可以使用-conf命令行参数来指定一个本地的xml配置文件。而在没有指定-conf参数的情况下,Hadoop则采用HADOOP_INSTALL/conf中xml作为其运行的配置文件。另外,也可以在Hadoop运行时,通过其它一些命令行参数为Hadoop运行提供单个的参数,这些参数构成了Hadoop执行的上下文--运行环境。比如:
Hadoop fs -conf /home/lianpeixun/hadoop-local.xml -ls
//指定一个本地配置文件作为Hadoop运行的配置文件
Hadoop fs -ls
//使用Hadoop安装目录下的conf中的配置文件作为其运行的环境参数
Hadoop fs -fs file:/// -ls
//指定特定的属性fs.default.name为file:///
Configured类实现了Configurable接口的getConf(),setConf()方法:
//获取Hadoop的运行上下文参数信息
public Configuration getConf();
//将Hadoop运行上下文参数信息传递给类
public void setConf(Configuration conf);
Tool接口
Tool接口是一个支持对一般的命令行选项进行处理的工具接口。Tool接口是所有Map-Reduce类型的工具和应用的标准实现接口。这些工具和应用将标准命令行选项交给ToolRunner.run来执行,从而使工具和应用只需关注它自己的参数就可以。实现了Tool接口的Map-Reduce类型的工具和应用中,简化了应用在运行时命令行参数信息的处理,使应用只需关注自身的参数。
二)流程
1)我们首先验证应用的参数个数是否正确,参数存在错误时,给出如何使用该应用的参数提示信息。2)参数验证正确后,我们得到Hadoop运行环境下的文件系统(FileSystem)、要读取的MapFile的路径path(Path)和要读取的键的对象key(Writable)。3)接着我们使用MapFileOutputFormat.getReaders(FileSystem fs,Path path,Configuration conf)静态方法得到要读取MapFile文件的输出数组readers(MapFile.Reader[])。readers是MapFile文件包含的所有输出的一个数组,这些数组中的每一个Reader记录了MapFile中的部分数据,数据在Reader中按照数据对的键(Key)的Hash值进行分布。4)为了得到键值key所在的readers数组中的哪一个Reader对象中,我们需要构建一个HashPartitioner类的对象partitioner。HashPartitioner类是一个利用键(key)/值(value)的哈希(object.hashCode())为数据进行分区的类。在创建了对象partitioner后,我们可以根据要查找的键key,得到键如果存在时,应该所在分区的索引--readers输出数组的下标。得到数组的下标后,我们就可以得到要查找的键Key所在的输出reader。5)我们使用reader.get(key,value)在reader中得到键key是否存在,如果不存在则退出。如果存在可通过reader.next()方法得到该reader()中所有的内容,并通过与键key的对比就可以得到键为key的所有的信息。
一)准备阶段
Configured基类
Configured基类实现了Configurable接口。Configurable接口的实现使该类具有在Hadoop环境下执行时,设置/获取Hadoop各种运行上下文参数的功能。在Hadoop运行时,可以使用-conf命令行参数来指定一个本地的xml配置文件。而在没有指定-conf参数的情况下,Hadoop则采用HADOOP_INSTALL/conf中xml作为其运行的配置文件。另外,也可以在Hadoop运行时,通过其它一些命令行参数为Hadoop运行提供单个的参数,这些参数构成了Hadoop执行的上下文--运行环境。比如:
Hadoop fs -conf /home/lianpeixun/hadoop-local.xml -ls
//指定一个本地配置文件作为Hadoop运行的配置文件
Hadoop fs -ls
//使用Hadoop安装目录下的conf中的配置文件作为其运行的环境参数
Hadoop fs -fs file:/// -ls
//指定特定的属性fs.default.name为file:///
Configured类实现了Configurable接口的getConf(),setConf()方法:
//获取Hadoop的运行上下文参数信息
public Configuration getConf();
//将Hadoop运行上下文参数信息传递给类
public void setConf(Configuration conf);
Tool接口
Tool接口是一个支持对一般的命令行选项进行处理的工具接口。Tool接口是所有Map-Reduce类型的工具和应用的标准实现接口。这些工具和应用将标准命令行选项交给ToolRunner.run来执行,从而使工具和应用只需关注它自己的参数就可以。实现了Tool接口的Map-Reduce类型的工具和应用中,简化了应用在运行时命令行参数信息的处理,使应用只需关注自身的参数。
二)流程
1)我们首先验证应用的参数个数是否正确,参数存在错误时,给出如何使用该应用的参数提示信息。2)参数验证正确后,我们得到Hadoop运行环境下的文件系统(FileSystem)、要读取的MapFile的路径path(Path)和要读取的键的对象key(Writable)。3)接着我们使用MapFileOutputFormat.getReaders(FileSystem fs,Path path,Configuration conf)静态方法得到要读取MapFile文件的输出数组readers(MapFile.Reader[])。readers是MapFile文件包含的所有输出的一个数组,这些数组中的每一个Reader记录了MapFile中的部分数据,数据在Reader中按照数据对的键(Key)的Hash值进行分布。4)为了得到键值key所在的readers数组中的哪一个Reader对象中,我们需要构建一个HashPartitioner类的对象partitioner。HashPartitioner类是一个利用键(key)/值(value)的哈希(object.hashCode())为数据进行分区的类。在创建了对象partitioner后,我们可以根据要查找的键key,得到键如果存在时,应该所在分区的索引--readers输出数组的下标。得到数组的下标后,我们就可以得到要查找的键Key所在的输出reader。5)我们使用reader.get(key,value)在reader中得到键key是否存在,如果不存在则退出。如果存在可通过reader.next()方法得到该reader()中所有的内容,并通过与键key的对比就可以得到键为key的所有的信息。
三)代码
View Code
1 /***
2 * 读取Mapfile文件
3 * @author Administrator
4 *
5 */
6 public class ReadMapfile extends Configured implements Tool {
7
8 @Override
9 public int run(String[] args) throws Exception {
10 //判断args参数个数
11 if(args.length!=2){
12 System.err.print("Usage:");
13 ToolRunner.printGenericCommandUsage(System.err);
14
15 return -1;
16 }
17 FileSystem fs=FileSystem.get(this.getConf());
18 Path path=new Path(args[1]);
19 IntWritable key=new IntWritable(Integer.parseInt(args[0]));
20
21 Reader[] readers=MapFileOutputFormat.getReaders(fs, path, this.getConf());
22 //得到指定值所在的reader
23 HashPartitioner<IntWritable,Text> partitioner=new HashPartitioner<IntWritable,Text>();
24 Text value=new Text();
25 int index=partitioner.getPartition(key, value, readers.length);
26 Reader reader=readers[index];
27 //检查是否存在,如果不存在就算了,不再麻烦 了。
28 Writable entry=reader.get(key, value);
29 if(entry==null){
30 return -1;
31 }
32 //如果存在,通过遍历的方式得到键为Key的就要得到所有的
33 IntWritable nextKey=new IntWritable();
34 do{
35 //
36 System.out.println(value.toString());
37 }while(reader.next(nextKey, value) && key.equals(nextKey));
38
39 return 0;
40 }
41
42 /**
43 * @param args
44 * @throws Exception
45 */
46 public static void main(String[] args) throws Exception {
47 int nExitCode=ToolRunner.run(new ReadMapfile(),args);
48
49 System.exit(nExitCode);
50 }
51 }
2 * 读取Mapfile文件
3 * @author Administrator
4 *
5 */
6 public class ReadMapfile extends Configured implements Tool {
7
8 @Override
9 public int run(String[] args) throws Exception {
10 //判断args参数个数
11 if(args.length!=2){
12 System.err.print("Usage:");
13 ToolRunner.printGenericCommandUsage(System.err);
14
15 return -1;
16 }
17 FileSystem fs=FileSystem.get(this.getConf());
18 Path path=new Path(args[1]);
19 IntWritable key=new IntWritable(Integer.parseInt(args[0]));
20
21 Reader[] readers=MapFileOutputFormat.getReaders(fs, path, this.getConf());
22 //得到指定值所在的reader
23 HashPartitioner<IntWritable,Text> partitioner=new HashPartitioner<IntWritable,Text>();
24 Text value=new Text();
25 int index=partitioner.getPartition(key, value, readers.length);
26 Reader reader=readers[index];
27 //检查是否存在,如果不存在就算了,不再麻烦 了。
28 Writable entry=reader.get(key, value);
29 if(entry==null){
30 return -1;
31 }
32 //如果存在,通过遍历的方式得到键为Key的就要得到所有的
33 IntWritable nextKey=new IntWritable();
34 do{
35 //
36 System.out.println(value.toString());
37 }while(reader.next(nextKey, value) && key.equals(nextKey));
38
39 return 0;
40 }
41
42 /**
43 * @param args
44 * @throws Exception
45 */
46 public static void main(String[] args) throws Exception {
47 int nExitCode=ToolRunner.run(new ReadMapfile(),args);
48
49 System.exit(nExitCode);
50 }
51 }