如何在MapReduce中使用sqoop生成的类?

时间:2012-07-19 16:20:25

标签: class import mapreduce sqoop

sqoop查询生成一个java文件,其中包含一个类,该类包含要在mapreduce中访问每行的列数据的代码。 (Sqoop导入是在没有--as-sequencefile选项的文本中完成的,每个记录有1行,列之间有逗号) 但是我们如何实际使用呢?

我在这个类中找到了一个公共方法parse(),它将Text作为输入并填充了类的所有成员,因此为了练习我修改了wordcount应用程序,将Mapopount中的TextInputFormat中的一行文本转换为sqoop生成的类的实例。但是当我调用parse()方法时,这会导致“未报告的exception.com.cloudera.sqoop.lib.RecordParser.ParseError;必须被捕获或声明被抛出”。

可以这样做,还是使用每条记录中的数据填充类所必需的自定义InputFormat?

1 个答案:

答案 0 :(得分:4)

好的,这一点很明显,一旦你发现,但作为一个java初学者,这可能需要时间。

首先配置您的项目: 只需在源文件夹中添加sqoop生成的.java文件即可。 我使用eclipse将它导入我的类源文件夹。

然后确保正确配置了项目的java构建路径:

在项目的properties / java build path / libraries / add external jar中添加以下jar文件: (对于hadoop cdh4 +):

/usr/lib/hadoop/hadoop-common.jar 
/usr/lib/hadoop-[version]-mapreduce/hadoop-core.jar
/usr/lib/sqoop/sqoop-[sqoop-version]-cdh[cdh-version].jar

然后调整你的mapreduce源代码: 首先配置它:

public int run(String [] args) throws exception
{
 Job job = new Job(getConf());
 job.setJarByClass(YourClass.class);
 job.setMapperClass(SqoopImportMap.class);
 job.setReducerClass(SqoopImprtReduce.class);

 FileInputFormat.addInputPath((job,"hdfs_path_to_your_sqoop_imported_file"));
 FileOutputFormat.setOutputPath((job,"hdfs_output_path"));

 // I simply use text as output for the mapper but it can be any class you designed
 // as long as you implement it as a Writable
 job.setMapOutputKeyClass(Text.Class);
 job.setMapOutputValueClass(Text.Class);

 job.setOutputKeyClass(Text.Class);
 job.setOutputValueClass(Text.Class);
 ...

现在配置你的mapper类。 假设您的sqoop导入的java文件名为Sqimp.java: 并且您导入的表具有以下列:id,name,age 你的mapper类应如下所示:

 public static class SqoopImportMap
 extends Mapper<LongWritable, Text, Text, Text> 
 {

 public void map(LongWritable k, Text v, Context context)
 {
  Sqimp s = new Sqimp(); 
  try
  {
  // this is where the code generated by sqoop is used.
  // it automatically casts one line of the imported data into an instance of the generated class, 
  // to let you access the data inside the columns easily
   s.parse(v);
  } 
  catch(ParseError pe) {// do something if there is an error.}

  try
  {
   // now the imported data is accessible:
   // e.g
   if (s.age>30)
   {
    // submit the selected data to the mapper's output as a key value pair.
    context.write(new Text(s.age),new Text(s.id));
   }
  }
  catch(Exception ex)
  {//do something about the error}
 }
}