5

sqoopクエリは、mapreduceで各行の列データにアクセスするためのコードを含むクラスを含むJavaファイルを生成します。(Sqoopのインポートは、-as-sequencefileオプションを使用せず、レコードごとに1行、列の間にコンマを使用してテキストで実行されました)しかし、実際にどのように使用するのでしょうか。

このクラスで、Textを入力として受け取り、クラスのすべてのメンバーにデータを入力するパブリックメソッドparse()を見つけたので、練習するために、wordcountアプリケーションを変更して、マッパーのTextInputFormatからのテキスト行を次のインスタンスに変換しました。 sqoopによって生成されたクラス。ただし、parse()メソッドを呼び出すと、「報告されていないexception.com.cloudera.sqoop.lib.RecordParser.ParseError;キャッチするか、スローするように宣言する必要があります」という原因になります。

この方法で実行できますか、それとも各レコードのデータをクラスに入力するためにカスタムInputFormatが必要ですか?

4

1 に答える 1

4

わかりました。これは、一度見つければ明らかなようですが、Javaの初心者としては時間がかかる場合があります。

最初にプロジェクトを構成します。sqoopで生成された.javaファイルをソースフォルダーに追加するだけです。Eclipseを使用してクラスソースフォルダーにインポートします。

次に、プロジェクトのJavaビルドパスが正しく構成されていることを確認してください。

プロジェクトのプロパティ/javaビルドパス/ライブラリ/外部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);
 ...

次に、マッパークラスを構成します。sqoopでインポートされたJavaファイルの名前がSqimp.javaであり、インポートしたテーブルに次の列があると仮定します:id、name、ageマッパークラスは次のようになります。

 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}
 }
}
于 2012-10-25T15:39:13.263 に答える